diff --git a/Telegram/Resources/art/sprite.png b/Telegram/Resources/art/sprite.png index e4de99008f..e8cdf61df2 100644 Binary files a/Telegram/Resources/art/sprite.png and b/Telegram/Resources/art/sprite.png differ diff --git a/Telegram/Resources/art/sprite_200x.png b/Telegram/Resources/art/sprite_200x.png index cd36753b0c..366203ca32 100644 Binary files a/Telegram/Resources/art/sprite_200x.png and b/Telegram/Resources/art/sprite_200x.png differ diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style index c0010e9277..c638b145c6 100644 --- a/Telegram/Resources/basic.style +++ b/Telegram/Resources/basic.style @@ -68,7 +68,7 @@ semiboldButtonBlueText: #2b99d5; wndMinHeight: 480px; wndDefWidth: 800px; wndDefHeight: 600px; -wndShadow: sprite(209px, 46px, 19px, 19px); +wndShadow: icon {{ "window_shadow", windowShadowFg }}; wndShadowShift: 1px; layerAlpha: 0.5; @@ -298,10 +298,11 @@ solidScroll: flatScroll { duration: 150; hiding: 0; } +defaultDropdownShadow: icon {{ "dropdown_shadow", windowShadowFg }}; defaultPopupMenu: PopupMenu { skip: 5px; - shadow: sprite(241px, 46px, 6px, 6px); + shadow: defaultDropdownShadow; shadowShift: 1px; itemBg: white; @@ -320,7 +321,7 @@ defaultPopupMenu: PopupMenu { separatorWidth: 1px; separatorFg: #f1f1f1; - arrow: sprite(0px, 126px, 4px, 7px); + arrow: icon {{ "dropdown_submenu_arrow", #373737 }}; duration: 120; @@ -689,7 +690,7 @@ btnIntroNext: flatButton(btnDefNext, btnDefBig) { radius: buttonRadius; } -boxShadow: sprite(363px, 50px, 15px, 15px); +boxShadow: icon {{ "box_shadow", windowShadowFg }}; boxShadowShift: 2px; introCountry: countryInput { @@ -1213,12 +1214,12 @@ btnBotKbHide: iconedButton(btnAttachEmoji) { downIcon: sprite(373px, 95px, 23px, 14px); downIconPos: point(5px, 17px); } -broadcastToggle: flatCheckbox { +silentToggle: flatCheckbox { textColor: black; bgColor: white; disColor: black; - width: 34px; + width: 33px; height: 46px; duration: 200; bgFunc: transition(easeOutCirc); @@ -1226,24 +1227,14 @@ broadcastToggle: flatCheckbox { font: normalFont; - imageRect: sprite(18px, 125px, 22px, 21px); - chkImageRect: sprite(40px, 125px, 22px, 21px); - overImageRect: sprite(40px, 104px, 22px, 21px); - chkOverImageRect: sprite(40px, 125px, 22px, 21px); - disImageRect: sprite(18px, 125px, 22px, 21px); - chkDisImageRect: sprite(18px, 125px, 22px, 21px); - - imagePos: point(6px, 12px); -} -silentToggle: flatCheckbox(broadcastToggle) { - width: 33px; - imageRect: sprite(354px, 242px, 21px, 21px); chkImageRect: sprite(354px, 221px, 21px, 21px); overImageRect: sprite(375px, 242px, 21px, 21px); chkOverImageRect: sprite(375px, 221px, 21px, 21px); disImageRect: sprite(354px, 242px, 21px, 21px); chkDisImageRect: sprite(354px, 221px, 21px, 21px); + + imagePos: point(6px, 12px); } btnRecordAudio: sprite(379px, 390px, 16px, 24px); btnRecordAudioActive: sprite(379px, 366px, 16px, 24px); @@ -1411,15 +1402,7 @@ btnCancelSearch: iconedButton(btnAddContact) { downIcon: sprite(188px, 43px, 18px, 18px); } -notifyBG: white; -notifyBorder: #f1f1f1; -notifyBorderWidth: 1px; -notifySlowHide: 4000; -notifyPhotoSize: 62px; -notifyMacPhotoSize: 64px; -notifyPhotoPos: point(9px, 9px); -notifyClosePos: point(1px, 2px); -notifyClose: iconedButton(btnDefIconed) { +simpleClose: iconedButton(btnDefIconed) { icon: sprite(167px, 130px, 10px, 10px); iconPos: point(10px, 10px); downIcon: sprite(167px, 130px, 10px, 10px); @@ -1428,17 +1411,6 @@ notifyClose: iconedButton(btnDefIconed) { width: 30px; height: 30px; } -notifyItemTop: 12px; -notifyTextLeft: 12px; -notifyTextTop: 7px; -notifySlowHideFunc: transition(easeInCirc); -notifyWaitShortHide: 0; -notifyWaitLongHide: 20000; -notifyFastAnim: 150; -notifyWidth: 316px; -notifyHeight: 80px; -notifyDeltaX: 6px; -notifyDeltaY: 7px; boxPhotoPadding: margins(28px, 28px, 28px, 18px); boxPhotoCompressedPadding: margins(0px, 2px, 0px, 22px); @@ -1540,17 +1512,15 @@ dropdownDef: dropdown { borderColor: #ebebeb; padding: margins(10px, 10px, 10px, 10px); - shadow: sprite(241px, 46px, 6px, 6px); + shadow: defaultDropdownShadow; shadowShift: 1px; duration: 150; width: 0px; } - -defaultInnerDropdownShadow: icon {{ "dropdown_shadow", windowShadowFg }}; defaultInnerDropdown: InnerDropdown { padding: margins(10px, 10px, 10px, 10px); - shadow: defaultInnerDropdownShadow; + shadow: defaultDropdownShadow; shadowShift: 1px; duration: 150; @@ -1840,7 +1810,7 @@ mvControlSize: 90px; mvIconSize: size(60px, 56px); mvDropdown: dropdown(dropdownDef) { - shadow: sprite(0px, 0px, 0px, 0px); + shadow: icon {}; padding: margins(11px, 12px, 11px, 12px); border: 0px; @@ -1865,7 +1835,7 @@ mvButton: iconedButton(btnDefIconed) { duration: 0; } mvPopupMenu: PopupMenu(defaultPopupMenu) { - shadow: sprite(0px, 0px, 0px, 0px); + shadow: icon {}; itemBg: #383838; itemBgOver: #505050; @@ -2044,7 +2014,7 @@ sessionInfoFont: msgFont; sessionInfoColor: #888888; sessionTerminateTop: 30px; sessionTerminateSkip: 18px; -sessionTerminate: iconedButton(notifyClose) { +sessionTerminate: iconedButton(simpleClose) { iconPos: point(3px, 3px); downIconPos: point(3px, 4px); width: 16px; @@ -2058,6 +2028,8 @@ webPageDescriptionFont: normalFont; webPagePhotoSize: 100px; webPagePhotoDelta: 8px; +mediaPlayerSuppressDuration: 150; + botDescSkip: 8px; suppressAll: 0.2; diff --git a/Telegram/Resources/basic_types.style b/Telegram/Resources/basic_types.style index 29724f60b6..73918d110e 100644 --- a/Telegram/Resources/basic_types.style +++ b/Telegram/Resources/basic_types.style @@ -233,7 +233,7 @@ dropdown { borderColor: color; padding: margins; - shadow: sprite; + shadow: icon; shadowShift: pixels; duration: int; @@ -255,7 +255,7 @@ InnerDropdown { PopupMenu { skip: pixels; - shadow: sprite; + shadow: icon; shadowShift: pixels; itemBg: color; @@ -273,7 +273,7 @@ PopupMenu { separatorWidth: pixels; separatorFg: color; - arrow: sprite; + arrow: icon; duration: int; diff --git a/Telegram/Resources/icons/box_shadow.png b/Telegram/Resources/icons/box_shadow.png new file mode 100644 index 0000000000..44d17254e6 Binary files /dev/null and b/Telegram/Resources/icons/box_shadow.png differ diff --git a/Telegram/Resources/icons/box_shadow@2x.png b/Telegram/Resources/icons/box_shadow@2x.png new file mode 100644 index 0000000000..06293b7405 Binary files /dev/null and b/Telegram/Resources/icons/box_shadow@2x.png differ diff --git a/Telegram/Resources/icons/dropdown_submenu_arrow.png b/Telegram/Resources/icons/dropdown_submenu_arrow.png new file mode 100644 index 0000000000..d7015e7e52 Binary files /dev/null and b/Telegram/Resources/icons/dropdown_submenu_arrow.png differ diff --git a/Telegram/Resources/icons/dropdown_submenu_arrow@2x.png b/Telegram/Resources/icons/dropdown_submenu_arrow@2x.png new file mode 100644 index 0000000000..49ca1c3936 Binary files /dev/null and b/Telegram/Resources/icons/dropdown_submenu_arrow@2x.png differ diff --git a/Telegram/Resources/icons/fade_horizontal_left.png b/Telegram/Resources/icons/fade_horizontal_left.png new file mode 100644 index 0000000000..93db9ad4ce Binary files /dev/null and b/Telegram/Resources/icons/fade_horizontal_left.png differ diff --git a/Telegram/Resources/icons/fade_horizontal_left@2x.png b/Telegram/Resources/icons/fade_horizontal_left@2x.png new file mode 100644 index 0000000000..d4e9f55a11 Binary files /dev/null and b/Telegram/Resources/icons/fade_horizontal_left@2x.png differ diff --git a/Telegram/Resources/icons/fade_horizontal_right.png b/Telegram/Resources/icons/fade_horizontal_right.png new file mode 100644 index 0000000000..f10b4f9246 Binary files /dev/null and b/Telegram/Resources/icons/fade_horizontal_right.png differ diff --git a/Telegram/Resources/icons/fade_horizontal_right@2x.png b/Telegram/Resources/icons/fade_horizontal_right@2x.png new file mode 100644 index 0000000000..ed229a5b79 Binary files /dev/null and b/Telegram/Resources/icons/fade_horizontal_right@2x.png differ diff --git a/Telegram/Resources/icons/monitor.png b/Telegram/Resources/icons/monitor.png new file mode 100644 index 0000000000..b1829c2b79 Binary files /dev/null and b/Telegram/Resources/icons/monitor.png differ diff --git a/Telegram/Resources/icons/monitor@2x.png b/Telegram/Resources/icons/monitor@2x.png new file mode 100644 index 0000000000..42356354f9 Binary files /dev/null and b/Telegram/Resources/icons/monitor@2x.png differ diff --git a/Telegram/Resources/icons/notification_send.png b/Telegram/Resources/icons/notification_send.png new file mode 100644 index 0000000000..f7f6bd47d8 Binary files /dev/null and b/Telegram/Resources/icons/notification_send.png differ diff --git a/Telegram/Resources/icons/notification_send@2x.png b/Telegram/Resources/icons/notification_send@2x.png new file mode 100644 index 0000000000..88998d2603 Binary files /dev/null and b/Telegram/Resources/icons/notification_send@2x.png differ diff --git a/Telegram/Resources/icons/window_shadow.png b/Telegram/Resources/icons/window_shadow.png new file mode 100644 index 0000000000..88f5ee95a5 Binary files /dev/null and b/Telegram/Resources/icons/window_shadow.png differ diff --git a/Telegram/Resources/icons/window_shadow@2x.png b/Telegram/Resources/icons/window_shadow@2x.png new file mode 100644 index 0000000000..d2e968fdb7 Binary files /dev/null and b/Telegram/Resources/icons/window_shadow@2x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 9573d6a0c2..b4815a8596 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -244,10 +244,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_settings_show_name" = "Show sender's name"; "lng_settings_show_preview" = "Show message preview"; "lng_settings_use_windows" = "Use Windows notifications"; +"lng_settings_use_native_notifications" = "Use native notifications"; +"lng_settings_advanced_notifications" = "Notifications position and count"; +"lng_settings_notifications_position" = "Location on the screen"; +"lng_settings_notifications_count" = "Notifications count"; "lng_settings_sound_notify" = "Play sound"; "lng_settings_include_muted" = "Include muted chats in unread count"; "lng_notification_preview" = "You have a new message"; +"lng_notification_reply" = "Reply"; +"lng_notification_hide_all" = "Hide all"; +"lng_notification_sample" = "This is a sample notification"; "lng_settings_section_general" = "General"; "lng_settings_change_lang" = "Change language"; @@ -567,7 +574,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_action_changed_title" = "{from} changed group name to «{title}»"; "lng_action_changed_title_channel" = "Channel name was changed to «{title}»"; "lng_action_created_chat" = "{from} created group «{title}»"; -"lng_action_created_channel" = "Channel «{title}» created"; +"lng_action_created_channel" = "Channel created"; "lng_action_group_migrate" = "The group was upgraded to a supergroup"; "lng_action_pinned_message" = "{from} pinned «{text}»"; "lng_action_pinned_media" = "{from} pinned {media}"; @@ -584,6 +591,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_action_pinned_media_game" = "the game «{game}»"; "lng_action_game_score" = "{from} scored {count:#|#|#} in {game}"; "lng_action_game_you_scored" = "You scored {count:#|#|#} in {game}"; +"lng_action_game_score_no_game" = "{from} scored {count:#|#|#}"; +"lng_action_game_you_scored_no_game" = "You scored {count:#|#|#}"; "lng_profile_migrate_reached" = "{count:_not_used_|# member|# members} limit reached"; "lng_profile_migrate_body" = "To get over this limit, you can upgrade your group to a supergroup."; diff --git a/Telegram/Resources/langs/lang_ko.strings b/Telegram/Resources/langs/lang_ko.strings index 11bfb8444d..b5da76074b 100644 --- a/Telegram/Resources/langs/lang_ko.strings +++ b/Telegram/Resources/langs/lang_ko.strings @@ -772,12 +772,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_allow_bot" = "허용"; "lng_bot_start" = "시작"; -"lng_bot_choose_group" = "Select a Group"; +"lng_bot_choose_group" = "그룹방 선택"; "lng_bot_no_groups" = "그룹이 존재하지 않습니다."; "lng_bot_groups_not_found" = "그룹을 찾을 수 없습니다."; "lng_bot_sure_invite" = "<<{group}>>에 봇을 추가 하시겠습니까?"; "lng_bot_already_in_group" = "봇이 이미 그룹의 멤버입니다."; -"lng_bot_choose_chat" = "Select a Chat"; +"lng_bot_choose_chat" = "채팅방 선택"; "lng_bot_no_chats" = "채팅방이 없습니다."; "lng_bot_chats_not_found" = "채팅방을 찾 을 수 없음"; "lng_bot_sure_share_game" = "{user}에게 게임을 공유하겠습니까?"; @@ -787,10 +787,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_user_typing" = "{user}님이 입력중입니다."; "lng_users_typing" = "{user}님과 {second_user}님이 입력중입니다."; "lng_many_typing" = "{count:_not_used_|#명이|#명이} 입력중입니다"; -"lng_playing_game" = "playing a game"; -"lng_user_playing_game" = "{user} is playing a game"; -"lng_users_playing_game" = "{user} and {second_user} are playing a game"; -"lng_many_playing_game" = "{count:_not_used_|# is|# are} playing a game"; +"lng_playing_game" = "게임 중"; +"lng_user_playing_game" = "{user}님이 게임 중입니다."; +"lng_users_playing_game" = "{user}님과 {second_user}님이 게임 중입니다."; +"lng_many_playing_game" = "{count:_not_used_|#명이|#명이} 게임 중입니다"; "lng_send_action_record_video" = "비디오 녹화 중"; "lng_user_action_record_video" = "{user}님이 녹화중입니다"; "lng_send_action_upload_video" = "비디오 전송 중"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 266393ad40..92a14d3230 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,10,8,5 - PRODUCTVERSION 0,10,8,5 + FILEVERSION 0,10,13,0 + PRODUCTVERSION 0,10,13,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.8.5" + VALUE "FileVersion", "0.10.13.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.8.5" + VALUE "ProductVersion", "0.10.13.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 5d7b4ab311..8e0ae490b9 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,10,8,5 - PRODUCTVERSION 0,10,8,5 + FILEVERSION 0,10,13,0 + PRODUCTVERSION 0,10,13,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.10.8.5" + VALUE "FileVersion", "0.10.13.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.8.5" + VALUE "ProductVersion", "0.10.13.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 524f195c6b..23e453beec 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "core/single_timer.h" + class ApiWrap : public QObject, public RPCSender { Q_OBJECT diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 28527ab3b9..d6a9208b3e 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -42,6 +42,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "numbers.h" #include "observer_peer.h" #include "window/chat_background.h" +#include "window/notifications_manager.h" namespace { App::LaunchState _launchState = App::Launched; @@ -1991,13 +1992,10 @@ namespace { if (::mousedItem == item) { mousedItem(nullptr); } - if (App::wnd()) { - App::wnd()->notifyItemRemoved(item); - } } void historyUnregItem(HistoryItem *item) { - MsgsData *data = fetchMsgsData(item->channelId(), false); + auto data = fetchMsgsData(item->channelId(), false); if (!data) return; auto i = data->find(item->id); @@ -2013,10 +2011,13 @@ namespace { std::swap(items, j.value()); ::dependentItems.erase(j); - for_const (HistoryItem *dependent, items) { + for_const (auto dependent, items) { dependent->dependencyItemRemoved(item); } } + if (auto manager = Window::Notifications::manager()) { + manager->clearFromItem(item); + } if (App::main() && !App::quitting()) { App::main()->itemRemoved(item); } diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index b30f64751b..351e5ca2b0 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "lang.h" #include "boxes/confirmbox.h" #include "ui/filedialog.h" +#include "ui/popupmenu.h" #include "langloaderplain.h" #include "localstorage.h" #include "autoupdater.h" @@ -35,6 +36,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "observer_peer.h" #include "window/chat_background.h" #include "media/player/media_player_instance.h" +#include "window/notifications_manager.h" #include "history/history_location_manager.h" namespace { @@ -303,9 +305,8 @@ void Application::readClients() { if (!startUrl.isEmpty()) { cSetStartUrl(startUrl); } - if (!cStartUrl().isEmpty() && App::main() && App::self()) { - App::main()->openLocalUrl(cStartUrl()); - cSetStartUrl(QString()); + if (auto main = App::main()) { + main->checkStartUrl(); } } @@ -332,8 +333,11 @@ void Application::closeApplication() { if (App::launchState() == App::QuitProcessed) return; App::setLaunchState(App::QuitProcessed); - delete AppObject; - AppObject = 0; + if (auto manager = Window::Notifications::manager()) { + manager->clearAllFast(); + } + + delete base::take(AppObject); Sandbox::finish(); @@ -729,6 +733,7 @@ AppClass::AppClass() : QObject() anim::startManager(); historyInit(); Media::Player::start(); + Window::Notifications::start(); DEBUG_LOG(("Application Info: inited...")); @@ -742,7 +747,8 @@ AppClass::AppClass() : QObject() DEBUG_LOG(("Application Info: starting app...")); - QMimeDatabase().mimeTypeForName(qsl("text/plain")); // create mime database + // Create mime database, so it won't be slow later. + QMimeDatabase().mimeTypeForName(qsl("text/plain")); _window = new MainWindow(); _window->createWinId(); @@ -1080,8 +1086,8 @@ void AppClass::checkMapVersion() { if (Local::oldMapVersion() < AppVersion) { if (Local::oldMapVersion()) { QString versionFeatures; - if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10003) { - versionFeatures = QString::fromUtf8("\xe2\x80\x94 New cute design for the Settings page"); + if ((cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10012) { + versionFeatures = QString::fromUtf8("Windows and Linux:\n\xe2\x80\x94 Quick reply from notifications\n\xe2\x80\x94 Hide all notifications button added\n\xe2\x80\x94 Change notifications location and maximum count\n\nLinux:\n\xe2\x80\x94 You can enable native notifications in Settings"); } else if (!(cAlphaVersion() || cBetaVersion()) && Local::oldMapVersion() < 10005) { versionFeatures = langNewVersionText(); } else { @@ -1098,8 +1104,9 @@ void AppClass::checkMapVersion() { AppClass::~AppClass() { Shortcuts::finish(); - auto window = createAndSwap(_window); - delete window; + delete base::take(_window); + + Window::Notifications::finish(); anim::stopManager(); @@ -1110,8 +1117,8 @@ AppClass::~AppClass() { MTP::finish(); AppObject = nullptr; - deleteAndMark(_uploader); - deleteAndMark(_translator); + delete base::take(_uploader); + delete base::take(_translator); Window::chatBackground()->reset(); @@ -1128,9 +1135,9 @@ AppClass *AppClass::app() { } MainWindow *AppClass::wnd() { - return AppObject ? AppObject->_window : 0; + return AppObject ? AppObject->_window : nullptr; } MainWidget *AppClass::main() { - return (AppObject && AppObject->_window) ? AppObject->_window->mainWidget() : 0; + return (AppObject && AppObject->_window) ? AppObject->_window->mainWidget() : nullptr; } diff --git a/Telegram/SourceFiles/application.h b/Telegram/SourceFiles/application.h index 60c2d520ba..27347b9800 100644 --- a/Telegram/SourceFiles/application.h +++ b/Telegram/SourceFiles/application.h @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwindow.h" #include "pspecific.h" +#include "core/single_timer.h" class UpdateChecker; class Application : public QApplication { diff --git a/Telegram/SourceFiles/boxes/abstractbox.cpp b/Telegram/SourceFiles/boxes/abstractbox.cpp index 7e6846c007..a9f4974f4f 100644 --- a/Telegram/SourceFiles/boxes/abstractbox.cpp +++ b/Telegram/SourceFiles/boxes/abstractbox.cpp @@ -160,7 +160,7 @@ void AbstractBox::resizeMaxHeight(int32 newWidth, int32 maxHeight) { move(r.left(), newTop); } } - parentWidget()->update(geometry().united(g).marginsAdded(QMargins(st::boxShadow.pxWidth(), st::boxShadow.pxHeight(), st::boxShadow.pxWidth(), st::boxShadow.pxHeight()))); + parentWidget()->update(geometry().united(g).marginsAdded(QMargins(st::boxShadow.width(), st::boxShadow.height(), st::boxShadow.width(), st::boxShadow.height()))); } } } diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index f97a39ff9b..5e561ff33c 100644 --- a/Telegram/SourceFiles/boxes/addcontactbox.cpp +++ b/Telegram/SourceFiles/boxes/addcontactbox.cpp @@ -1405,7 +1405,7 @@ void RevokePublicLinkBox::mousePressEvent(QMouseEvent *e) { } void RevokePublicLinkBox::mouseReleaseEvent(QMouseEvent *e) { - auto pressed = createAndSwap(_pressed); + auto pressed = base::take(_pressed); setCursor((_selected || _pressed) ? style::cur_pointer : style::cur_default); if (pressed && pressed == _selected) { auto text_method = pressed->isMegagroup() ? lng_channels_too_much_public_revoke_confirm_group : lng_channels_too_much_public_revoke_confirm_channel; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 61f024f8b5..306381f21b 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -89,3 +89,24 @@ shareColumnSkip: 6px; shareSelectDuration: 150; shareActivateDuration: 150; shareScrollDuration: 300; + +notificationsBoxHeight: 450px; +notificationsBoxMonitorTop: 63px; +notificationsBoxMonitor: icon {{ "monitor", #000000 }}; +notificationsBoxScreenTop: 10px; +notificationsBoxScreenSize: size(280px, 160px); +notificationsBoxScreenBg: titleBg; +notificationsBoxCountLabelTop: 80px; +notificationsBoxCountTop: 30px; + +notificationsSampleSkip: 5px; +notificationsSampleTopSkip: 5px; +notificationsSampleBottomSkip: 5px; +notificationsSampleMargin: 2px; + +notificationSampleOpacity: 0.5; +notificationSampleSize: size(64px, 16px); +notificationSampleUserpicFg: #40ace3; +notificationSampleCloseFg: #d7d7d7; +notificationSampleTextFg: #d7d7d7; +notificationSampleNameFg: #939393; diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 1d3976e6d7..646421224f 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "abstractbox.h" +#include "core/single_timer.h" namespace Dialogs { class Row; diff --git a/Telegram/SourceFiles/boxes/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp new file mode 100644 index 0000000000..172e2b67fc --- /dev/null +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -0,0 +1,421 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "boxes/notifications_box.h" + +#include "lang.h" +#include "ui/buttons/round_button.h" +#include "ui/widgets/discrete_slider.h" +#include "styles/style_boxes.h" +#include "styles/style_dialogs.h" +#include "styles/style_window.h" +#include "application.h" +#include "localstorage.h" + +namespace { + +constexpr int kMaxNotificationsCount = 5; + +} // namespace + +class NotificationsBox::SampleWidget : public QWidget { +public: + SampleWidget(NotificationsBox *owner, const QPixmap &cache) : QWidget(nullptr) + , _owner(owner) + , _cache(cache) { + resize(cache.width() / cache.devicePixelRatio(), cache.height() / cache.devicePixelRatio()); + + setAttribute(Qt::WA_MacAlwaysShowToolWindow); + setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_OpaquePaintEvent); + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint); + + setWindowOpacity(0.); + show(); + } + + void detach() { + _owner = nullptr; + hideFast(); + } + + void showFast() { + _hiding = false; + startAnimation(); + } + + void hideFast() { + _hiding = true; + startAnimation(); + } + +protected: + virtual void paintEvent(QPaintEvent *e) { + Painter p(this); + p.drawPixmap(0, 0, _cache); + } + +private: + void startAnimation() { + _opacity.start([this] { animationCallback(); }, _hiding ? 1. : 0., _hiding ? 0. : 1., st::notifyFastAnim); + } + void animationCallback() { + setWindowOpacity(_opacity.current(_hiding ? 0. : 1.)); + if (!_opacity.animating() && _hiding) { + if (_owner) { + _owner->removeSample(this); + } + hide(); + destroyDelayed(); + } + } + + void destroyDelayed() { + if (_deleted) return; + _deleted = true; + + // Ubuntu has a lag if deleteLater() called immediately. +#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 + QTimer::singleShot(1000, [this] { delete this; }); +#else // Q_OS_LINUX32 || Q_OS_LINUX64 + deleteLater(); +#endif // Q_OS_LINUX32 || Q_OS_LINUX64 + } + + NotificationsBox *_owner; + QPixmap _cache; + FloatAnimation _opacity; + bool _hiding = false; + bool _deleted = false; + +}; + +NotificationsBox::NotificationsBox() : AbstractBox() +, _chosenCorner(Global::NotificationsCorner()) +, _oldCount(snap(Global::NotificationsCount(), 1, kMaxNotificationsCount)) +, _countSlider(this) +, _done(this, lang(lng_about_done), st::defaultBoxButton) { + _sampleOpacities.reserve(kMaxNotificationsCount); + for (int i = 0; i != kMaxNotificationsCount; ++i) { + _countSlider->addSection(QString::number(i + 1)); + _sampleOpacities.push_back(FloatAnimation()); + } + _countSlider->setActiveSectionFast(_oldCount - 1); + _countSlider->setSectionActivatedCallback([this] { countChanged(); }); + + setMouseTracking(true); + _done->setClickedCallback([this] { onClose(); }); + + prepareNotificationSampleSmall(); + prepareNotificationSampleLarge(); + setMaxHeight(st::notificationsBoxHeight); + + prepare(); +} + +void NotificationsBox::paintEvent(QPaintEvent *e) { + Painter p(this); + if (paint(p)) return; + + auto contentLeft = getContentLeft(); + + p.setFont(st::boxTitleFont); + p.setPen(st::boxTitleFg); + p.drawTextLeft(contentLeft, st::boxTitlePosition.y(), width(), lang(lng_settings_notifications_position)); + + auto screenRect = getScreenRect(); + p.fillRect(screenRect.x(), screenRect.y(), st::notificationsBoxScreenSize.width(), st::notificationsBoxScreenSize.height(), st::notificationsBoxScreenBg); + + auto monitorTop = st::notificationsBoxMonitorTop; + st::notificationsBoxMonitor.paint(p, contentLeft, monitorTop, width()); + + for (int corner = 0; corner != 4; ++corner) { + auto screenCorner = static_cast(corner); + auto isLeft = Notify::IsLeftCorner(screenCorner); + auto isTop = Notify::IsTopCorner(screenCorner); + auto sampleLeft = isLeft ? (screenRect.x() + st::notificationsSampleSkip) : (screenRect.x() + screenRect.width() - st::notificationsSampleSkip - st::notificationSampleSize.width()); + auto sampleTop = isTop ? (screenRect.y() + st::notificationsSampleTopSkip) : (screenRect.y() + screenRect.height() - st::notificationsSampleBottomSkip - st::notificationSampleSize.height()); + if (corner == static_cast(_chosenCorner)) { + auto count = currentCount(); + for (int i = 0; i != kMaxNotificationsCount; ++i) { + auto opacity = _sampleOpacities[i].current(getms(), (i < count) ? 1. : 0.); + p.setOpacity(opacity); + p.drawPixmapLeft(sampleLeft, sampleTop, width(), _notificationSampleSmall); + sampleTop += (isTop ? 1 : -1) * (st::notificationSampleSize.height() + st::notificationsSampleMargin); + } + } else { + p.setOpacity(st::notificationSampleOpacity); + p.drawPixmapLeft(sampleLeft, sampleTop, width(), _notificationSampleSmall); + p.setOpacity(1.); + } + } + + auto labelTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop; + p.drawTextLeft(contentLeft, labelTop, width(), lang(lng_settings_notifications_count)); +} + +void NotificationsBox::countChanged() { + auto count = currentCount(); + auto moreSamples = (count > _oldCount); + auto from = moreSamples ? 0. : 1.; + auto to = moreSamples ? 1. : 0.; + auto indexDelta = moreSamples ? 1 : -1; + auto animatedDelta = moreSamples ? 0 : -1; + for (; _oldCount != count; _oldCount += indexDelta) { + _sampleOpacities[_oldCount + animatedDelta].start([this] { update(); }, from, to, st::notifyFastAnim); + } + + if (currentCount() != Global::NotificationsCount()) { + Global::SetNotificationsCount(currentCount()); + Global::RefNotifySettingsChanged().notify(Notify::ChangeType::MaxCount); + Local::writeUserSettings(); + } +} + +int NotificationsBox::getContentLeft() const { + return (width() - st::notificationsBoxMonitor.width()) / 2; +} + +QRect NotificationsBox::getScreenRect() const { + auto screenLeft = (width() - st::notificationsBoxScreenSize.width()) / 2; + auto screenTop = st::notificationsBoxMonitorTop + st::notificationsBoxScreenTop; + return QRect(screenLeft, screenTop, st::notificationsBoxScreenSize.width(), st::notificationsBoxScreenSize.height()); +} + +void NotificationsBox::resizeEvent(QResizeEvent *e) { + _done->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _done->height()); + + auto screenRect = getScreenRect(); + auto sliderTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop + st::notificationsBoxCountTop; + auto contentLeft = getContentLeft(); + _countSlider->resizeToWidth(width() - 2 * contentLeft); + _countSlider->move(contentLeft, sliderTop); + AbstractBox::resizeEvent(e); +} + +void NotificationsBox::prepareNotificationSampleSmall() { + auto width = st::notificationSampleSize.width(); + auto height = st::notificationSampleSize.height(); + auto sampleImage = QImage(width * cIntRetinaFactor(), height * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + sampleImage.setDevicePixelRatio(cRetinaFactor()); + sampleImage.fill(st::notifyBg->c); + { + Painter p(&sampleImage); + p.setPen(Qt::NoPen); + p.setRenderHint(QPainter::HighQualityAntialiasing); + + auto padding = height / 8; + auto userpicSize = height - 2 * padding; + p.setBrush(st::notificationSampleUserpicFg); + p.drawEllipse(rtlrect(padding, padding, userpicSize, userpicSize, width)); + + auto rowLeft = height; + auto rowHeight = padding; + auto nameTop = (height - 5 * padding) / 2; + auto nameWidth = height; + p.setBrush(st::notificationSampleNameFg); + p.drawRoundedRect(rtlrect(rowLeft, nameTop, nameWidth, rowHeight, width), rowHeight / 2, rowHeight / 2); + + auto rowWidth = (width - rowLeft - 3 * padding); + auto rowTop = nameTop + rowHeight + padding; + p.setBrush(st::notificationSampleTextFg); + p.drawRoundedRect(rtlrect(rowLeft, rowTop, rowWidth, rowHeight, width), rowHeight / 2, rowHeight / 2); + rowTop += rowHeight + padding; + p.drawRoundedRect(rtlrect(rowLeft, rowTop, rowWidth, rowHeight, width), rowHeight / 2, rowHeight / 2); + + auto closeLeft = width - 2 * padding; + p.fillRect(rtlrect(closeLeft, padding, padding, padding, width), st::notificationSampleCloseFg); + } + _notificationSampleSmall = App::pixmapFromImageInPlace(std_::move(sampleImage)); + _notificationSampleSmall.setDevicePixelRatio(cRetinaFactor()); +} + +void NotificationsBox::prepareNotificationSampleUserpic() { + if (_notificationSampleUserpic.isNull()) { + _notificationSampleUserpic = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize * cIntRetinaFactor(), st::notifyPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + _notificationSampleUserpic.setDevicePixelRatio(cRetinaFactor()); + } +} + +void NotificationsBox::prepareNotificationSampleLarge() { + int w = st::notifyWidth, h = st::notifyMinHeight; + auto sampleImage = QImage(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + sampleImage.setDevicePixelRatio(cRetinaFactor()); + sampleImage.fill(st::notifyBg->c); + { + Painter p(&sampleImage); + p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); + p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); + + prepareNotificationSampleUserpic(); + p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), _notificationSampleUserpic); + + int itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; + + auto rectForName = rtlrect(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height, w); + + auto notifyText = st::dialogsTextFont->elided(lang(lng_notification_sample), itemWidth); + p.setFont(st::dialogsTextFont); + p.setPen(st::dialogsTextFgService); + p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText); + + p.setPen(st::dialogsNameFg); + p.setFont(st::msgNameFont); + + auto notifyTitle = st::msgNameFont->elided(qsl("Telegram Desktop"), rectForName.width()); + p.drawText(rectForName.left(), rectForName.top() + st::msgNameFont->ascent, notifyTitle); + + p.setOpacity(st::notifyClose.opacity); + p.drawSpriteLeft(w - st::notifyClosePos.x() - st::notifyClose.width + st::notifyClose.iconPos.x(), st::notifyClosePos.y() + st::notifyClose.iconPos.y(), w, st::notifyClose.icon); + } + + _notificationSampleLarge = App::pixmapFromImageInPlace(std_::move(sampleImage)); +} + +void NotificationsBox::removeSample(SampleWidget *widget) { + for (auto &samples : _cornerSamples) { + for (int i = 0, size = samples.size(); i != size; ++i) { + if (samples[i] == widget) { + for (int j = i + 1; j != size; ++j) { + samples[j]->detach(); + } + samples.resize(i); + break; + } + } + } +} + +void NotificationsBox::mouseMoveEvent(QMouseEvent *e) { + auto screenRect = getScreenRect(); + auto cornerWidth = screenRect.width() / 3; + auto cornerHeight = screenRect.height() / 3; + auto topLeft = rtlrect(screenRect.x(), screenRect.y(), cornerWidth, cornerHeight, width()); + auto topRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y(), cornerWidth, cornerHeight, width()); + auto bottomRight = rtlrect(screenRect.x() + screenRect.width() - cornerWidth, screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width()); + auto bottomLeft = rtlrect(screenRect.x(), screenRect.y() + screenRect.height() - cornerHeight, cornerWidth, cornerHeight, width()); + if (topLeft.contains(e->pos())) { + setOverCorner(Notify::ScreenCorner::TopLeft); + } else if (topRight.contains(e->pos())) { + setOverCorner(Notify::ScreenCorner::TopRight); + } else if (bottomRight.contains(e->pos())) { + setOverCorner(Notify::ScreenCorner::BottomRight); + } else if (bottomLeft.contains(e->pos())) { + setOverCorner(Notify::ScreenCorner::BottomLeft); + } else { + clearOverCorner(); + } +} + +void NotificationsBox::leaveEvent(QEvent *e) { + clearOverCorner(); +} + +void NotificationsBox::setOverCorner(Notify::ScreenCorner corner) { + if (_isOverCorner) { + if (corner == _overCorner) { + return; + } + for_const (auto widget, _cornerSamples[static_cast(_overCorner)]) { + widget->hideFast(); + } + } else { + _isOverCorner = true; + setCursor(style::cur_pointer); + Global::SetNotificationsDemoIsShown(true); + Global::RefNotifySettingsChanged().notify(Notify::ChangeType::DemoIsShown); + } + _overCorner = corner; + + auto &samples = _cornerSamples[static_cast(_overCorner)]; + auto samplesAlready = samples.size(); + auto samplesNeeded = currentCount(); + auto samplesLeave = qMin(samplesAlready, samplesNeeded); + for (int i = 0; i != samplesLeave; ++i) { + samples[i]->showFast(); + } + if (samplesNeeded > samplesLeave) { + auto r = psDesktopRect(); + auto isLeft = Notify::IsLeftCorner(_overCorner); + auto isTop = Notify::IsTopCorner(_overCorner); + auto sampleLeft = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX); + auto sampleTop = isTop ? (r.y() + st::notifyDeltaY) : (r.y() + r.height() - st::notifyDeltaY - st::notifyMinHeight); + for (int i = samplesLeave; i != samplesNeeded; ++i) { + auto widget = std_::make_unique(this, _notificationSampleLarge); + widget->move(sampleLeft, sampleTop + (isTop ? 1 : -1) * i * (st::notifyMinHeight + st::notifyDeltaY)); + widget->showFast(); + samples.push_back(widget.release()); + } + } else { + for (int i = samplesLeave; i != samplesAlready; ++i) { + samples[i]->hideFast(); + } + } +} + +void NotificationsBox::clearOverCorner() { + if (_isOverCorner) { + _isOverCorner = false; + setCursor(style::cur_default); + Global::SetNotificationsDemoIsShown(false); + Global::RefNotifySettingsChanged().notify(Notify::ChangeType::DemoIsShown); + + for_const (auto &samples, _cornerSamples) { + for_const (auto widget, samples) { + widget->hideFast(); + } + } + } +} + +int NotificationsBox::currentCount() const { + return _countSlider->activeSection() + 1; +} + +void NotificationsBox::mousePressEvent(QMouseEvent *e) { + _isDownCorner = _isOverCorner; + _downCorner = _overCorner; +} + +void NotificationsBox::mouseReleaseEvent(QMouseEvent *e) { + auto isDownCorner = base::take(_isDownCorner); + if (isDownCorner && _isOverCorner && _downCorner == _overCorner && _downCorner != _chosenCorner) { + _chosenCorner = _downCorner; + update(); + + if (_chosenCorner != Global::NotificationsCorner()) { + Global::SetNotificationsCorner(_chosenCorner); + Global::RefNotifySettingsChanged().notify(Notify::ChangeType::Corner); + Local::writeUserSettings(); + } + } +} + +NotificationsBox::~NotificationsBox() { + for_const (auto &samples, _cornerSamples) { + for_const (auto widget, samples) { + widget->detach(); + } + } + clearOverCorner(); +} diff --git a/Telegram/SourceFiles/boxes/notifications_box.h b/Telegram/SourceFiles/boxes/notifications_box.h new file mode 100644 index 0000000000..36bcfdbce6 --- /dev/null +++ b/Telegram/SourceFiles/boxes/notifications_box.h @@ -0,0 +1,79 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "abstractbox.h" + +class BoxButton; +class LinkButton; + +namespace Ui { +class DiscreteSlider; +} // namespace Ui + +class NotificationsBox : public AbstractBox { +public: + NotificationsBox(); + ~NotificationsBox(); + +protected: + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void leaveEvent(QEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + +private: + using ScreenCorner = Notify::ScreenCorner; + void countChanged(); + void setOverCorner(ScreenCorner corner); + void clearOverCorner(); + + class SampleWidget; + void removeSample(SampleWidget *widget); + + int currentCount() const; + + QRect getScreenRect() const; + int getContentLeft() const; + void prepareNotificationSampleSmall(); + void prepareNotificationSampleLarge(); + void prepareNotificationSampleUserpic(); + + QPixmap _notificationSampleUserpic; + QPixmap _notificationSampleSmall; + QPixmap _notificationSampleLarge; + ScreenCorner _chosenCorner; + std_::vector_of_moveable _sampleOpacities; + + bool _isOverCorner = false; + ScreenCorner _overCorner = ScreenCorner::TopLeft; + bool _isDownCorner = false; + ScreenCorner _downCorner = ScreenCorner::TopLeft; + + int _oldCount; + ChildWidget _countSlider; + ChildWidget _done; + + QVector _cornerSamples[4]; + +}; diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index e845390cc1..42cb287ff6 100644 --- a/Telegram/SourceFiles/boxes/report_box.cpp +++ b/Telegram/SourceFiles/boxes/report_box.cpp @@ -83,11 +83,11 @@ void ReportBox::onChange() { connect(_reasonOtherText, SIGNAL(submitted(bool)), this, SLOT(onReport())); connect(_reasonOtherText, SIGNAL(cancelled()), this, SLOT(onClose())); } + _reasonOtherText->setFocus(); } else if (_reasonOtherText) { _reasonOtherText.destroy(); updateMaxHeight(); } - _reasonOtherText->setFocus(); } void ReportBox::doSetInnerFocus() { diff --git a/Telegram/SourceFiles/boxes/sessionsbox.h b/Telegram/SourceFiles/boxes/sessionsbox.h index 51f84d0214..851bfa8fba 100644 --- a/Telegram/SourceFiles/boxes/sessionsbox.h +++ b/Telegram/SourceFiles/boxes/sessionsbox.h @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "abstractbox.h" +#include "core/single_timer.h" class ConfirmBox; diff --git a/Telegram/SourceFiles/boxes/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h index 113ac8aa32..71001d8f92 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.h +++ b/Telegram/SourceFiles/boxes/stickersetbox.h @@ -337,7 +337,7 @@ private: int _dragging = -1; int _above = -1; - BoxShadow _aboveShadow; + Ui::RectShadow _aboveShadow; int32 _scrollbar = 0; }; diff --git a/Telegram/SourceFiles/codegen/style/parsed_file.cpp b/Telegram/SourceFiles/codegen/style/parsed_file.cpp index a7acde2317..f45ecebad5 100644 --- a/Telegram/SourceFiles/codegen/style/parsed_file.cpp +++ b/Telegram/SourceFiles/codegen/style/parsed_file.cpp @@ -769,10 +769,6 @@ structure::Value ParsedFile::readIconValue() { } } - if (parts.empty()) { - logErrorUnexpectedToken() << "at least one icon part"; - return {}; - } return { structure::data::icon { parts } }; } file_.putBack(); diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index ab0ac7de76..a9ef7f033e 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -97,9 +97,6 @@ enum { MediaOverviewStartPerPage = 5, MediaOverviewPreloadCount = 4, - // a new message from the same sender is attached to previous within 15 minutes - AttachMessageToPreviousSecondsDelta = 900, - AudioSimultaneousLimit = 4, AudioCheckPositionTimeout = 100, // 100ms per check audio pos AudioCheckPositionDelta = 2400, // update position called each 2400 samples @@ -215,7 +212,7 @@ Efzk2DWgkBluml8OREmvfraX3bkHZJTKX4EQSjBbbdJ2ZXIsRrYOXfaA+xayEGB+\n\ 8hdlLmAjbCVfaigxX0CDqWeR1yFL9kwd9P0NsZRPsmoqVwMbMu7mStFai6aIhc3n\n\ Slv8kg9qv1m6XHVQY3PnEw+QQtqSIXklHwIDAQAB\n\ -----END RSA PUBLIC KEY-----"}; - keysCount = arraysize(keys); + keysCount = base::array_size(keys); return keys; } @@ -292,6 +289,10 @@ static const int32 ApiId = 17349; static const char *ApiHash = "344583e45741c457fe1862106095a5eb"; #endif +#if Q_BYTE_ORDER == Q_BIG_ENDIAN +#error "Only little endian is supported!" +#endif // Q_BYTE_ORDER == Q_BIG_ENDIAN + #ifndef BETA_VERSION_MACRO #error "Beta version macro is not defined." #endif @@ -375,9 +376,7 @@ enum { WaitForChannelGetDifference = 1000, // 1s wait after show channel history before sending getChannelDifference MemoryForImageCache = 64 * 1024 * 1024, // after 64mb of unpacked images we try to clear some memory - NotifyWindowsCount = 3, // 3 desktop notifies at the same time NotifySettingSaveTimeout = 1000, // wait 1 second before saving notify setting to server - NotifyDeletePhotoAfter = 60000, // delete notify photo after 1 minute UpdateChunk = 100 * 1024, // 100kb parts when downloading the update IdleMsecs = 60 * 1000, // after 60secs without user input we think we are idle diff --git a/Telegram/SourceFiles/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp index 45f331df3a..53ea0b47d5 100644 --- a/Telegram/SourceFiles/core/click_handler_types.cpp +++ b/Telegram/SourceFiles/core/click_handler_types.cpp @@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/qthelp_regex.h" #include "core/qthelp_url.h" #include "localstorage.h" +#include "ui/popupmenu.h" QString UrlClickHandler::copyToClipboardContextItemText() const { return lang(isEmail() ? lng_context_copy_email : lng_context_copy_link); diff --git a/Telegram/SourceFiles/core/lambda_wrap.h b/Telegram/SourceFiles/core/lambda_wrap.h index b8c6c8e531..22e1ed4381 100644 --- a/Telegram/SourceFiles/core/lambda_wrap.h +++ b/Telegram/SourceFiles/core/lambda_wrap.h @@ -20,9 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#ifndef OS_MAC_OLD -#include -#endif // OS_MAC_OLD +#include "core/stl_subset.h" namespace base { namespace internal { @@ -392,191 +390,3 @@ public: }; } // namespace base - -// While we still use rpcDone() and rpcFail() - -#include "mtproto/rpc_sender.h" - -template -struct LambdaUniqueHelper; - -template -struct LambdaUniqueHelper { - using UniqueType = base::lambda_unique; -}; - -template -using LambdaGetUnique = typename LambdaUniqueHelper::UniqueType; - -template -class RPCHandlerImplementation : public Base { -protected: - using Lambda = base::lambda_unique; - using Parent = RPCHandlerImplementation; - -public: - RPCHandlerImplementation(Lambda &&handler) : _handler(std_::move(handler)) { - } - -protected: - Lambda _handler; - -}; - -template -using RPCDoneHandlerImplementation = RPCHandlerImplementation; - -template -class RPCDoneHandlerImplementationBare : public RPCDoneHandlerImplementation { // done(from, end) -public: - using RPCDoneHandlerImplementation::Parent::Parent; - void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { - return this->_handler ? this->_handler(from, end) : void(0); - } - -}; - -template -class RPCDoneHandlerImplementationBareReq : public RPCDoneHandlerImplementation { // done(from, end, req_id) -public: - using RPCDoneHandlerImplementation::Parent::Parent; - void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { - return this->_handler ? this->_handler(from, end, requestId) : void(0); - } - -}; - -template -class RPCDoneHandlerImplementationPlain : public RPCDoneHandlerImplementation { // done(result) -public: - using RPCDoneHandlerImplementation::Parent::Parent; - void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { - return this->_handler ? this->_handler(T(from, end)) : void(0); - } - -}; - -template -class RPCDoneHandlerImplementationReq : public RPCDoneHandlerImplementation { // done(result, req_id) -public: - using RPCDoneHandlerImplementation::Parent::Parent; - void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { - return this->_handler ? this->_handler(T(from, end), requestId) : void(0); - } - -}; - -template -class RPCDoneHandlerImplementationNo : public RPCDoneHandlerImplementation { // done() -public: - using RPCDoneHandlerImplementation::Parent::Parent; - void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { - return this->_handler ? this->_handler() : void(0); - } - -}; - -template -class RPCDoneHandlerImplementationNoReq : public RPCDoneHandlerImplementation { // done(req_id) -public: - using RPCDoneHandlerImplementation::Parent::Parent; - void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { - return this->_handler ? this->_handler(requestId) : void(0); - } - -}; - -template -inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationBare(std_::move(lambda))); -} - -template -inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationBareReq(std_::move(lambda))); -} - -template -inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationPlain(std_::move(lambda))); -} - -template -inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationReq(std_::move(lambda))); -} - -template -inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationNo(std_::move(lambda))); -} - -template -inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationNoReq(std_::move(lambda))); -} - -template ::value>> -RPCDoneHandlerPtr rpcDone(Lambda &&lambda) { - return rpcDone_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); -} - -template -using RPCFailHandlerImplementation = RPCHandlerImplementation; - -class RPCFailHandlerImplementationPlain : public RPCFailHandlerImplementation { // fail(error) -public: - using Parent::Parent; - bool operator()(mtpRequestId requestId, const RPCError &error) const override { - return _handler ? _handler(error) : true; - } - -}; - -class RPCFailHandlerImplementationReq : public RPCFailHandlerImplementation { // fail(error, req_id) -public: - using Parent::Parent; - bool operator()(mtpRequestId requestId, const RPCError &error) const override { - return this->_handler ? this->_handler(error, requestId) : true; - } - -}; - -class RPCFailHandlerImplementationNo : public RPCFailHandlerImplementation { // fail() -public: - using Parent::Parent; - bool operator()(mtpRequestId requestId, const RPCError &error) const override { - return this->_handler ? this->_handler() : true; - } - -}; - -class RPCFailHandlerImplementationNoReq : public RPCFailHandlerImplementation { // fail(req_id) -public: - using Parent::Parent; - bool operator()(mtpRequestId requestId, const RPCError &error) const override { - return this->_handler ? this->_handler(requestId) : true; - } - -}; - -inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCFailHandlerPtr(new RPCFailHandlerImplementationPlain(std_::move(lambda))); -} - -inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCFailHandlerPtr(new RPCFailHandlerImplementationReq(std_::move(lambda))); -} - -inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCFailHandlerPtr(new RPCFailHandlerImplementationNo(std_::move(lambda))); -} - -inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { - return RPCFailHandlerPtr(new RPCFailHandlerImplementationNoReq(std_::move(lambda))); -} - -template ::value>> -RPCFailHandlerPtr rpcFail(Lambda &&lambda) { - return rpcFail_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); -} diff --git a/Telegram/SourceFiles/core/observer.h b/Telegram/SourceFiles/core/observer.h index 0b220ce171..d071893097 100644 --- a/Telegram/SourceFiles/core/observer.h +++ b/Telegram/SourceFiles/core/observer.h @@ -60,7 +60,7 @@ public: Subscription() = default; Subscription(const Subscription &) = delete; Subscription &operator=(const Subscription &) = delete; - Subscription(Subscription &&other) : _node(createAndSwap(other._node)), _removeMethod(other._removeMethod) { + Subscription(Subscription &&other) : _node(base::take(other._node)), _removeMethod(other._removeMethod) { } Subscription &operator=(Subscription &&other) { qSwap(_node, other._node); @@ -258,7 +258,7 @@ public: private: void callHandlers() { _handling = true; - auto events = createAndSwap(_events); + auto events = base::take(_events); for (auto &event : events) { this->notifyEnumerate([this, &event]() { this->_current->handler(event); @@ -305,7 +305,7 @@ public: private: void callHandlers() { _handling = true; - auto eventsCount = createAndSwap(_eventsCount); + auto eventsCount = base::take(_eventsCount); for (int i = 0; i != eventsCount; ++i) { this->notifyEnumerate([this]() { this->_current->handler(); @@ -352,7 +352,7 @@ protected: } ~Subscriber() { - auto subscriptions = createAndSwap(_subscriptions); + auto subscriptions = base::take(_subscriptions); for (auto &subscription : subscriptions) { subscription.destroy(); } diff --git a/Telegram/SourceFiles/core/single_timer.cpp b/Telegram/SourceFiles/core/single_timer.cpp new file mode 100644 index 0000000000..7507a8f14b --- /dev/null +++ b/Telegram/SourceFiles/core/single_timer.cpp @@ -0,0 +1,80 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "core/single_timer.h" + +#include "application.h" + +SingleTimer::SingleTimer() { + QTimer::setSingleShot(true); + if (App::app()) { + connect(App::app(), SIGNAL(adjustSingleTimers()), this, SLOT(adjust())); + _inited = true; + } +} + +void SingleTimer::setTimeoutHandler(base::lambda_unique &&handler) { + if (_handler && !handler) { + disconnect(this, SIGNAL(timeout()), this, SLOT(onTimeout())); + } else if (handler && !_handler) { + connect(this, SIGNAL(timeout()), this, SLOT(onTimeout())); + } + _handler = std_::move(handler); +} + +void SingleTimer::adjust() { + uint64 n = getms(true); + if (isActive()) { + if (n >= _finishing) { + start(0); + } else { + start(_finishing - n); + } + } +} + +void SingleTimer::onTimeout() { + if (_handler) { + _handler(); + } +} + +void SingleTimer::start(int msec) { + _finishing = getms(true) + (msec < 0 ? 0 : uint64(msec)); + if (!_inited && App::app()) { + connect(App::app(), SIGNAL(adjustSingleTimers()), this, SLOT(adjust())); + _inited = true; + } + QTimer::start(msec); +} + +void SingleTimer::startIfNotActive(int msec) { + if (isActive()) { + int remains = remainingTime(); + if (remains > msec) { + start(msec); + } else if (!remains) { + start(1); + } + } else { + start(msec); + } +} diff --git a/Telegram/SourceFiles/core/single_timer.h b/Telegram/SourceFiles/core/single_timer.h new file mode 100644 index 0000000000..3aa89647a9 --- /dev/null +++ b/Telegram/SourceFiles/core/single_timer.h @@ -0,0 +1,50 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "core/basic_types.h" +#include "core/lambda_wrap.h" + +class SingleTimer : public QTimer { // single shot timer with check + Q_OBJECT + +public: + SingleTimer(); + + void setSingleShot(bool); // is not available + void start(); // is not available + + void setTimeoutHandler(base::lambda_unique &&handler); + +public slots: + void start(int msec); + void startIfNotActive(int msec); + +private slots: + void adjust(); + void onTimeout(); + +private: + uint64 _finishing = 0; + bool _inited = false; + base::lambda_unique _handler; + +}; diff --git a/Telegram/SourceFiles/core/utils.cpp b/Telegram/SourceFiles/core/utils.cpp index 4ad8140abd..63959c2720 100644 --- a/Telegram/SourceFiles/core/utils.cpp +++ b/Telegram/SourceFiles/core/utils.cpp @@ -345,36 +345,6 @@ uint64 getms(bool checked) { #endif } -SingleTimer::SingleTimer() : _finishing(0), _inited(false) { - QTimer::setSingleShot(true); - if (App::app()) { - connect(App::app(), SIGNAL(adjustSingleTimers()), this, SLOT(adjust())); - _inited = true; - } -} - -void SingleTimer::start(int msec) { - _finishing = getms(true) + (msec < 0 ? 0 : uint64(msec)); - if (!_inited && App::app()) { - connect(App::app(), SIGNAL(adjustSingleTimers()), this, SLOT(adjust())); - _inited = true; - } - QTimer::start(msec); -} - -void SingleTimer::startIfNotActive(int msec) { - if (isActive()) { - int remains = remainingTime(); - if (remains > msec) { - start(msec); - } else if (!remains) { - start(1); - } - } else { - start(msec); - } -} - uint64 msgid() { #ifdef Q_OS_WIN LARGE_INTEGER li; diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h index c672c263b2..117410ab08 100644 --- a/Telegram/SourceFiles/core/utils.h +++ b/Telegram/SourceFiles/core/utils.h @@ -22,23 +22,21 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/basic_types.h" +namespace base { + template -inline constexpr size_t arraysize(T(&ArrahSizeHelper)[N]) { +inline constexpr size_t array_size(T(&)[N]) { return N; } template -void deleteAndMark(T *&link) { - delete link; - link = reinterpret_cast(0x00000BAD); +inline T take(T &source) { + T result = T(); + std_::swap_moveable(result, source); + return std_::move(result); } -template -T *getPointerAndReset(T *&ptr) { - T *result = nullptr; - qSwap(result, ptr); - return result; -} +} // namespace base template inline QFlags qFlags(Enum v) { @@ -87,13 +85,6 @@ inline void accumulate_max(T &a, const T &b) { if (a < b) a = b; } template inline void accumulate_min(T &a, const T &b) { if (a > b) a = b; } -template -T createAndSwap(T &value) { - T result = T(); - std_::swap_moveable(result, value); - return std_::move(result); -} - static volatile int *t_assert_nullptr = nullptr; inline void t_noop() {} inline void t_assert_fail(const char *message, const char *file, int32 line) { @@ -172,37 +163,6 @@ void finish(); bool checkms(); // returns true if time has changed uint64 getms(bool checked = false); -class SingleTimer : public QTimer { // single shot timer with check - Q_OBJECT - -public: - - SingleTimer(); - - void setSingleShot(bool); // is not available - void start(); // is not available - - public slots: - - void start(int msec); - void startIfNotActive(int msec); - void adjust() { - uint64 n = getms(true); - if (isActive()) { - if (n >= _finishing) { - start(0); - } else { - start(_finishing - n); - } - } - } - -private: - uint64 _finishing; - bool _inited; - -}; - const static uint32 _md5_block_size = 64; class HashMd5 { public: @@ -508,7 +468,7 @@ public: return _p; } T *release() { - return getPointerAndReset(_p); + return base::take(_p); } void reset(T *p = nullptr) { delete _p; @@ -551,7 +511,7 @@ public: return _p; } T *release() { - return getPointerAndReset(_p); + return base::take(_p); } void reset(T *p = nullptr) { delete _p; diff --git a/Telegram/SourceFiles/core/vector_of_moveable.h b/Telegram/SourceFiles/core/vector_of_moveable.h index e83005c075..727bbac2db 100644 --- a/Telegram/SourceFiles/core/vector_of_moveable.h +++ b/Telegram/SourceFiles/core/vector_of_moveable.h @@ -36,9 +36,9 @@ public: vector_of_moveable(const vector_of_moveable &other) = delete; vector_of_moveable &operator=(const vector_of_moveable &other) = delete; vector_of_moveable(vector_of_moveable &&other) - : _size(createAndSwap(other._size)) - , _capacity(createAndSwap(other._capacity)) - , _plaindata(createAndSwap(other._plaindata)) { + : _size(base::take(other._size)) + , _capacity(base::take(other._capacity)) + , _plaindata(base::take(other._plaindata)) { } vector_of_moveable &operator=(vector_of_moveable &&other) { std_::swap_moveable(_size, other._size); diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index edc0a521ec..bc9856a6c9 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,9 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/utils.h" -#define BETA_VERSION_MACRO (10008005ULL) +#define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10008; -constexpr str_const AppVersionStr = "0.10.8"; -constexpr bool AppAlphaVersion = false; +constexpr int AppVersion = 10013; +constexpr str_const AppVersionStr = "0.10.13"; +constexpr bool AppAlphaVersion = true; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 757f55c108..66778d0f85 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dialogs/dialogs_layout.h" #include "styles/style_dialogs.h" #include "ui/buttons/round_button.h" +#include "ui/popupmenu.h" #include "data/data_drafts.h" #include "lang.h" #include "application.h" @@ -122,8 +123,8 @@ void DialogsInner::paintRegion(Painter &p, const QRegion ®ion, bool paintingO p.fillRect(0, 0, w, st::mentionHeight, (selected ? st::mentionBgOver : st::white)->b); if (!paintingOther) { if (selected) { - int skip = (st::mentionHeight - st::notifyClose.icon.pxHeight()) / 2; - p.drawSprite(QPoint(w - st::notifyClose.icon.pxWidth() - skip, skip), st::notifyClose.icon); + int skip = (st::mentionHeight - st::simpleClose.icon.pxHeight()) / 2; + p.drawSprite(QPoint(w - st::simpleClose.icon.pxWidth() - skip, skip), st::simpleClose.icon); } QString first = (_hashtagFilter.size() < 2) ? QString() : ('#' + _hashtagResults.at(from).mid(0, _hashtagFilter.size() - 1)), second = (_hashtagFilter.size() < 2) ? ('#' + _hashtagResults.at(from)) : _hashtagResults.at(from).mid(_hashtagFilter.size() - 1); int32 firstwidth = st::mentionFont->width(first), secondwidth = st::mentionFont->width(second); @@ -478,7 +479,6 @@ void DialogsInner::removeDialog(History *history) { if (importantDialogs) { history->removeFromChatList(Dialogs::Mode::Important, importantDialogs.get()); } - history->clearNotifications(); if (App::wnd()) App::wnd()->notifyClear(history); if (contacts->contains(history->peer->id)) { if (!contactsNoDialogs->contains(history->peer->id)) { diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index 743705025d..78ed3d010c 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -22,7 +22,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/section_widget.h" -class MainWidget; namespace Dialogs { class Row; class FakeRow; @@ -33,6 +32,9 @@ namespace Ui { class RoundButton; } // namespace Ui +class MainWidget; +class PopupMenu; + enum DialogsSearchRequestType { DialogsSearchFromStart, DialogsSearchFromOffset, diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 1045d9bb08..5876eeff9c 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -122,7 +122,7 @@ void Dropdown::resizeEvent(QResizeEvent *e) { } void Dropdown::paintEvent(QPaintEvent *e) { - QPainter p(this); + Painter p(this); if (_a_appearance.animating()) { p.setOpacity(a_opacity.current()); @@ -358,7 +358,7 @@ void DragArea::setText(const QString &text, const QString &subtext) { } void DragArea::paintEvent(QPaintEvent *e) { - QPainter p(this); + Painter p(this); if (_a_appearance.animating()) { p.setOpacity(a_opacity.current()); diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h index 836b2a5315..a9ed3f6992 100644 --- a/Telegram/SourceFiles/dropdown.h +++ b/Telegram/SourceFiles/dropdown.h @@ -21,7 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "ui/twidget.h" -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" class Dropdown : public TWidget { Q_OBJECT @@ -91,7 +91,7 @@ private: QTimer _hideTimer; - BoxShadow _shadow; + Ui::RectShadow _shadow; }; @@ -101,13 +101,6 @@ class DragArea : public TWidget { public: DragArea(QWidget *parent); - void paintEvent(QPaintEvent *e); - void mouseMoveEvent(QMouseEvent *e); - void dragEnterEvent(QDragEnterEvent *e); - void dragLeaveEvent(QDragLeaveEvent *e); - void dropEvent(QDropEvent *e); - void dragMoveEvent(QDragMoveEvent *e); - void setText(const QString &text, const QString &subtext); void otherEnter(); @@ -127,6 +120,14 @@ public: ).contains(QRect(mapFromGlobal(globalRect.topLeft()), globalRect.size())); } +protected: + void paintEvent(QPaintEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void dragEnterEvent(QDragEnterEvent *e) override; + void dragLeaveEvent(QDragLeaveEvent *e) override; + void dropEvent(QDropEvent *e) override; + void dragMoveEvent(QDragMoveEvent *e) override; + signals: void dropped(const QMimeData *data); @@ -143,7 +144,7 @@ private: anim::cvalue a_color; Animation _a_appearance; - BoxShadow _shadow; + Ui::RectShadow _shadow; QString _text, _subtext; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index afd0d4cc2e..ca9fed4ec3 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -634,8 +634,10 @@ struct Data { bool RestoreSoundNotifyFromTray = false; bool IncludeMuted = true; DBINotifyView NotifyView = dbinvShowPreview; - bool WindowsNotifications = true; - bool CustomNotifies = (cPlatform() == dbipMac) ? false : true; + bool NativeNotifications = false; + int NotificationsCount = 3; + Notify::ScreenCorner NotificationsCorner = Notify::ScreenCorner::BottomRight; + bool NotificationsDemoIsShown = false; base::Observable NotifySettingsChanged; DBIConnectionType ConnectionType = dbictAuto; @@ -742,8 +744,10 @@ DefineVar(Global, bool, DesktopNotify); DefineVar(Global, bool, RestoreSoundNotifyFromTray); DefineVar(Global, bool, IncludeMuted); DefineVar(Global, DBINotifyView, NotifyView); -DefineVar(Global, bool, WindowsNotifications); -DefineVar(Global, bool, CustomNotifies); +DefineVar(Global, bool, NativeNotifications); +DefineVar(Global, int, NotificationsCount); +DefineVar(Global, Notify::ScreenCorner, NotificationsCorner); +DefineVar(Global, bool, NotificationsDemoIsShown); DefineRefVar(Global, base::Observable, NotifySettingsChanged); DefineVar(Global, DBIConnectionType, ConnectionType); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 53c8d32dba..3a6a67ba24 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -148,9 +148,26 @@ enum class ChangeType { IncludeMuted, DesktopEnabled, ViewParams, - UseNative, + MaxCount, + Corner, + DemoIsShown, }; +enum class ScreenCorner { + TopLeft = 0, + TopRight = 1, + BottomRight = 2, + BottomLeft = 3, +}; + +inline bool IsLeftCorner(ScreenCorner corner) { + return (corner == ScreenCorner::TopLeft) || (corner == ScreenCorner::BottomLeft); +} + +inline bool IsTopCorner(ScreenCorner corner) { + return (corner == ScreenCorner::TopLeft) || (corner == ScreenCorner::TopRight); +} + } // namespace Notify #define DeclareReadOnlyVar(Type, Name) const Type &Name(); @@ -309,8 +326,10 @@ DeclareVar(bool, DesktopNotify); DeclareVar(bool, RestoreSoundNotifyFromTray); DeclareVar(bool, IncludeMuted); DeclareVar(DBINotifyView, NotifyView); -DeclareVar(bool, WindowsNotifications); -DeclareVar(bool, CustomNotifies); +DeclareVar(bool, NativeNotifications); +DeclareVar(int, NotificationsCount); +DeclareVar(Notify::ScreenCorner, NotificationsCorner); +DeclareVar(bool, NotificationsDemoIsShown); DeclareRefVar(base::Observable, NotifySettingsChanged); DeclareVar(DBIConnectionType, ConnectionType); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index ab7705a41c..b9df529256 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -1427,7 +1427,6 @@ MsgId History::inboxRead(MsgId upTo) { showFrom = nullptr; App::wnd()->notifyClear(this); - clearNotifications(); return upTo; } diff --git a/Telegram/SourceFiles/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index 5b710363fc..5ef830b473 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.cpp +++ b/Telegram/SourceFiles/history/field_autocomplete.cpp @@ -28,13 +28,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org FieldAutocomplete::FieldAutocomplete(QWidget *parent) : TWidget(parent) , _scroll(this, st::mentionScroll) , _inner(this, &_mrows, &_hrows, &_brows, &_srows) -, _chat(0) -, _user(0) -, _channel(0) -, _hiding(false) , a_opacity(0) -, _a_appearance(animation(this, &FieldAutocomplete::step_appearance)) -, _shadow(st::dropdownDef.shadow) { +, _a_appearance(animation(this, &FieldAutocomplete::step_appearance)) { _hideTimer.setSingleShot(true); connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart())); @@ -605,9 +600,9 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) { bool selected = (i == _sel); if (selected) { p.fillRect(0, i * st::mentionHeight, width(), st::mentionHeight, st::mentionBgOver->b); - int skip = (st::mentionHeight - st::notifyClose.icon.pxHeight()) / 2; + int skip = (st::mentionHeight - st::simpleClose.icon.pxHeight()) / 2; if (!_hrows->isEmpty() || (!_mrows->isEmpty() && i < _recentInlineBotsInRows)) { - p.drawSprite(QPoint(width() - st::notifyClose.icon.pxWidth() - skip, i * st::mentionHeight + skip), st::notifyClose.icon); + p.drawSprite(QPoint(width() - st::simpleClose.icon.pxWidth() - skip, i * st::mentionHeight + skip), st::simpleClose.icon); } } p.setPen(st::black->p); diff --git a/Telegram/SourceFiles/history/field_autocomplete.h b/Telegram/SourceFiles/history/field_autocomplete.h index 9f824a8297..d0579b16b7 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.h +++ b/Telegram/SourceFiles/history/field_autocomplete.h @@ -21,7 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "ui/twidget.h" -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" namespace internal { @@ -91,9 +91,10 @@ public slots: void showStart(); -private: +protected: void paintEvent(QPaintEvent *e) override; +private: void updateFiltered(bool resetScroll = false); void recount(bool resetScroll = false); @@ -108,9 +109,9 @@ private: ChildWidget _scroll; ChildWidget _inner; - ChatData *_chat; - UserData *_user; - ChannelData *_channel; + ChatData *_chat = nullptr; + UserData *_user = nullptr; + ChannelData *_channel = nullptr; EmojiPtr _emoji; enum class Type { Mentions, @@ -124,14 +125,13 @@ private: bool _addInlineBots; int32 _width, _height; - bool _hiding; + bool _hiding = false; anim::fvalue a_opacity; Animation _a_appearance; QTimer _hideTimer; - BoxShadow _shadow; friend class internal::FieldAutocompleteInner; }; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 6b71261e3e..c4d8c2978d 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -28,6 +28,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_dialogs.h" #include "fileuploader.h" +namespace { + +// a new message from the same sender is attached to previous within 15 minutes +constexpr int kAttachMessageToPreviousSecondsDelta = 900; + +} // namespace + ReplyMarkupClickHandler::ReplyMarkupClickHandler(const HistoryItem *item, int row, int col) : _itemId(item->fullId()) , _row(row) @@ -352,7 +359,7 @@ void HistoryMessageReplyMarkup::createFromButtonRows(const QVectorserviceMsg() && !previos->isEmpty() && previos->from() == from() - && (qAbs(previos->date.secsTo(date)) < AttachMessageToPreviousSecondsDelta); + && (qAbs(previos->date.secsTo(date)) < kAttachMessageToPreviousSecondsDelta); } } if (attach && !(_flags & MTPDmessage_ClientFlag::f_attach_to_previous)) { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 3be1f86650..d1cd61d501 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -199,6 +199,7 @@ struct HistoryMessageReplyMarkup : public RuntimeComponent()) { + if (auto fwd = Get()) { return fwd->_fromOriginal; } return from(); } PeerData *authorOriginal() const { - if (const HistoryMessageForwarded *fwd = Get()) { + if (auto fwd = Get()) { return fwd->_authorOriginal; } return author(); @@ -837,7 +838,7 @@ public: void clipCallback(Media::Clip::Notification notification); - virtual ~HistoryItem(); + ~HistoryItem(); protected: HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from); @@ -898,6 +899,12 @@ protected: void recountAttachToPrevious(); const HistoryMessageReplyMarkup *inlineReplyMarkup() const { + return const_cast(this)->inlineReplyMarkup(); + } + const ReplyKeyboard *inlineReplyKeyboard() const { + return const_cast(this)->inlineReplyKeyboard(); + } + HistoryMessageReplyMarkup *inlineReplyMarkup() { if (auto markup = Get()) { if (markup->flags & MTPDreplyKeyboardMarkup_ClientFlag::f_inline) { return markup; @@ -905,18 +912,12 @@ protected: } return nullptr; } - const ReplyKeyboard *inlineReplyKeyboard() const { + ReplyKeyboard *inlineReplyKeyboard() { if (auto markup = inlineReplyMarkup()) { return markup->inlineKeyboard.get(); } return nullptr; } - HistoryMessageReplyMarkup *inlineReplyMarkup() { - return const_cast(static_cast(this)->inlineReplyMarkup()); - } - ReplyKeyboard *inlineReplyKeyboard() { - return const_cast(static_cast(this)->inlineReplyKeyboard()); - } TextSelection toMediaSelection(TextSelection selection) const { return internal::unshiftSelection(selection, _text); diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 3505b01f55..d49f6a1f4b 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -232,7 +232,7 @@ void HistoryFileMedia::checkAnimationFinished() { } HistoryFileMedia::~HistoryFileMedia() { - deleteAndMark(_animation); + delete base::take(_animation); } HistoryPhoto::HistoryPhoto(HistoryItem *parent, PhotoData *photo, const QString &caption) : HistoryFileMedia(parent) @@ -2562,7 +2562,7 @@ int HistoryWebPage::resizeGetHeight(int width) { return _height; } - _width = width = qMin(width, _maxw); + _width = width/* = qMin(width, _maxw)*/; width -= st::msgPadding.left() + st::webPageLeft + st::msgPadding.right(); int32 linesMax = 5; @@ -2686,9 +2686,9 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, u } else { pix = _data->photo->thumb->pixBlurredSingle(ImageRoundRadius::Small, pixw, pixh, pw, ph); } - p.drawPixmapLeft(padding.left() + width - pw, 0, _width, pix); + p.drawPixmapLeft(padding.left() + width - pw, tshift, _width, pix); if (selected) { - App::roundRect(p, rtlrect(padding.left() + width - pw, 0, pw, _pixh, _width), textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners); + App::roundRect(p, rtlrect(padding.left() + width - pw, tshift, pw, _pixh, _width), textstyleCurrent()->selectOverlay, SelectedOverlaySmallCorners); } width -= pw + st::webPagePhotoDelta; } diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h index 45c0ea3eae..68c913dc10 100644 --- a/Telegram/SourceFiles/history/history_media_types.h +++ b/Telegram/SourceFiles/history/history_media_types.h @@ -309,7 +309,7 @@ struct HistoryDocumentVoice : public RuntimeComponent { return *this; } ~HistoryDocumentVoice() { - deleteAndMark(_playback); + delete base::take(_playback); } void ensurePlayback(const HistoryDocument *interfaces) const; void checkPlaybackFinished() const; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index dc23b998d0..7e7779f0d0 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -366,7 +366,7 @@ HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) CreateConfig config; if (msg.has_fwd_from() && msg.vfwd_from.type() == mtpc_messageFwdHeader) { - const auto &f(msg.vfwd_from.c_messageFwdHeader()); + auto &f = msg.vfwd_from.c_messageFwdHeader(); if (f.has_from_id() || f.has_channel_id()) { config.authorIdOriginal = f.has_channel_id() ? peerFromChannel(f.vchannel_id) : peerFromUser(f.vfrom_id); config.fromIdOriginal = f.has_from_id() ? peerFromUser(f.vfrom_id) : peerFromChannel(f.vchannel_id); @@ -376,7 +376,7 @@ HistoryMessage::HistoryMessage(History *history, const MTPDmessage &msg) if (msg.has_reply_to_msg_id()) config.replyTo = msg.vreply_to_msg_id.v; if (msg.has_via_bot_id()) config.viaBotId = msg.vvia_bot_id.v; if (msg.has_views()) config.viewsCount = msg.vviews.v; - if (msg.has_reply_markup()) config.markup = &msg.vreply_markup; + if (msg.has_reply_markup()) config.mtpMarkup = &msg.vreply_markup; if (msg.has_edit_date()) config.editDate = ::date(msg.vedit_date); createComponents(config); @@ -435,9 +435,15 @@ HistoryMessage::HistoryMessage(History *history, MsgId id, MTPDmessage::Flags fl config.viewsCount = 1; } + // Copy inline keyboard when forwarding messages with a game. + auto mediaOriginal = fwd->getMedia(); + if (mediaOriginal && mediaOriginal->type() == MediaTypeGame) { + config.inlineMarkup = fwd->inlineReplyMarkup(); + } + createComponents(config); - if (HistoryMedia *mediaOriginal = fwd->getMedia()) { + if (mediaOriginal) { _media.reset(mediaOriginal->clone(this)); } setText(fwd->originalText()); @@ -479,7 +485,7 @@ void HistoryMessage::createComponentsHelper(MTPDmessage::Flags flags, MsgId repl if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId; if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo; - if (flags & MTPDmessage::Flag::f_reply_markup) config.markup = &markup; + if (flags & MTPDmessage::Flag::f_reply_markup) config.mtpMarkup = &markup; if (isPost()) config.viewsCount = 1; createComponents(config); @@ -518,8 +524,10 @@ void HistoryMessage::updateMediaInBubbleState() { _media->setInBubbleState(computeState()); } -bool HistoryMessage::displayEditedBadge(bool hasViaBot) const { - if (!(_flags & MTPDmessage::Flag::f_edit_date)) { +bool HistoryMessage::displayEditedBadge(bool hasViaBotOrInlineMarkup) const { + if (hasViaBotOrInlineMarkup) { + return false; + } else if (!(_flags & MTPDmessage::Flag::f_edit_date)) { return false; } if (auto fromUser = from()->asUser()) { @@ -527,9 +535,6 @@ bool HistoryMessage::displayEditedBadge(bool hasViaBot) const { return false; } } - if (hasViaBot) { - return false; - } return true; } @@ -548,20 +553,31 @@ void HistoryMessage::createComponents(const CreateConfig &config) { if (isPost() && _from->isUser()) { mask |= HistoryMessageSigned::Bit(); } - if (displayEditedBadge(config.viaBotId != 0)) { + auto hasViaBot = (config.viaBotId != 0); + auto hasInlineMarkup = [&config] { + if (config.mtpMarkup) { + return (config.mtpMarkup->type() == mtpc_replyInlineMarkup); + } + return (config.inlineMarkup != nullptr); + }; + if (displayEditedBadge(hasViaBot || hasInlineMarkup())) { mask |= HistoryMessageEdited::Bit(); } if (config.authorIdOriginal && config.fromIdOriginal) { mask |= HistoryMessageForwarded::Bit(); } - if (config.markup) { + if (config.mtpMarkup) { // optimization: don't create markup component for the case // MTPDreplyKeyboardHide with flags = 0, assume it has f_zero flag - if (config.markup->type() != mtpc_replyKeyboardHide || config.markup->c_replyKeyboardHide().vflags.v != 0) { + if (config.mtpMarkup->type() != mtpc_replyKeyboardHide || config.mtpMarkup->c_replyKeyboardHide().vflags.v != 0) { mask |= HistoryMessageReplyMarkup::Bit(); } + } else if (config.inlineMarkup) { + mask |= HistoryMessageReplyMarkup::Bit(); } + UpdateComponents(mask); + if (auto reply = Get()) { reply->replyToMsgId = config.replyTo; if (!reply->updateData(this) && App::api()) { @@ -586,7 +602,11 @@ void HistoryMessage::createComponents(const CreateConfig &config) { fwd->_originalId = config.originalId; } if (auto markup = Get()) { - markup->create(*config.markup); + if (config.mtpMarkup) { + markup->create(*config.mtpMarkup); + } else if (config.inlineMarkup) { + markup->create(*config.inlineMarkup); + } if (markup->flags & MTPDreplyKeyboardMarkup_ClientFlag::f_has_switch_inline_button) { _flags |= MTPDmessage_ClientFlag::f_has_switch_inline_button; } @@ -829,7 +849,9 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) { if (message.has_edit_date()) { _flags |= MTPDmessage::Flag::f_edit_date; - if (displayEditedBadge(Has())) { + auto hasViaBotId = Has(); + auto hasInlineMarkup = (inlineReplyMarkup() != nullptr); + if (displayEditedBadge(hasViaBotId || hasInlineMarkup)) { if (!Has()) { AddComponents(HistoryMessageEdited::Bit()); } @@ -1808,7 +1830,7 @@ void HistoryService::setMessageByAction(const MTPmessageAction &action) { case mtpc_messageActionChannelCreate: { auto &d = action.c_messageActionChannelCreate(); if (isPost()) { - text = lng_action_created_channel(lt_title, textClean(qs(d.vtitle))); + text = lang(lng_action_created_channel); } else { text = lng_action_created_chat(lt_from, from, lt_title, textClean(qs(d.vtitle))); } @@ -2009,12 +2031,21 @@ bool HistoryService::prepareGameScoreText(const QString &from, QString *outText, gameTitle = lang(lng_contacts_loading); result = true; } else { - gameTitle = lang(lng_deleted_message); + gameTitle = QString(); } + auto scoreNumber = gamescore ? gamescore->score : 0; if (_from->isSelf()) { - *outText = lng_action_game_you_scored(lt_count, gamescore->score, lt_game, gameTitle); + if (gameTitle.isEmpty()) { + *outText = lng_action_game_you_scored_no_game(lt_count, scoreNumber); + } else { + *outText = lng_action_game_you_scored(lt_count, scoreNumber, lt_game, gameTitle); + } } else { - *outText = lng_action_game_score(lt_from, from, lt_count, gamescore->score, lt_game, gameTitle); + if (gameTitle.isEmpty()) { + *outText = lng_action_game_score_no_game(lt_from, from, lt_count, scoreNumber); + } else { + *outText = lng_action_game_score(lt_from, from, lt_count, scoreNumber, lt_game, gameTitle); + } } if (second) { outLinks->push_back(second); @@ -2212,12 +2243,13 @@ HistoryTextState HistoryService::getState(int x, int y, HistoryStateRequest requ } void HistoryService::createFromMtp(const MTPDmessageService &message) { + if (message.vaction.type() == mtpc_messageActionGameScore) { + UpdateComponents(HistoryServiceGameScore::Bit()); + Get()->score = message.vaction.c_messageActionGameScore().vscore.v; + } if (message.has_reply_to_msg_id()) { if (message.vaction.type() == mtpc_messageActionPinMessage) { UpdateComponents(HistoryServicePinned::Bit()); - } else if (message.vaction.type() == mtpc_messageActionGameScore) { - UpdateComponents(HistoryServiceGameScore::Bit()); - Get()->score = message.vaction.c_messageActionGameScore().vscore.v; } if (auto dependent = GetDependentData()) { dependent->msgId = message.vreply_to_msg_id.v; diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index c52e6490c5..0a1408c9b3 100644 --- a/Telegram/SourceFiles/history/history_message.h +++ b/Telegram/SourceFiles/history/history_message.h @@ -63,7 +63,7 @@ public: return (!emptyText() || !_media || !_media->isDisplayed() || Has() || Has() || viaBot() || !_media->hideFromName()); } - bool displayEditedBadge(bool hasViaBot) const; + bool displayEditedBadge(bool hasViaBotOrInlineMarkup) const; bool uploading() const { return _media && _media->uploading(); } @@ -191,7 +191,12 @@ private: PeerId fromIdOriginal = 0; MsgId originalId = 0; QDateTime editDate; - const MTPReplyMarkup *markup = nullptr; + + // For messages created from MTP structs. + const MTPReplyMarkup *mtpMarkup = nullptr; + + // For messages created from existing messages (forwarded). + const HistoryMessageReplyMarkup *inlineMarkup = nullptr; }; void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, int32 viaBotId, const MTPReplyMarkup &markup); void createComponents(const CreateConfig &config); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 8acdfad514..c71496b34f 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2638,85 +2638,53 @@ void BotKeyboard::updateSelected() { } HistoryHider::HistoryHider(MainWidget *parent, bool forwardSelected) : TWidget(parent) -, _sharedContact(0) , _forwardSelected(forwardSelected) -, _sendPath(false) , _send(this, lang(lng_forward_send), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) -, offered(0) , a_opacity(0, 1) , _a_appearance(animation(this, &HistoryHider::step_appearance)) -, hiding(false) -, _forwardRequest(0) -, toTextWidth(0) -, shadow(st::boxShadow) { +, _shadow(st::boxShadow) { init(); } HistoryHider::HistoryHider(MainWidget *parent, UserData *sharedContact) : TWidget(parent) , _sharedContact(sharedContact) -, _forwardSelected(false) -, _sendPath(false) , _send(this, lang(lng_forward_send), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) -, offered(0) , a_opacity(0, 1) , _a_appearance(animation(this, &HistoryHider::step_appearance)) -, hiding(false) -, _forwardRequest(0) -, toTextWidth(0) -, shadow(st::boxShadow) { +, _shadow(st::boxShadow) { init(); } HistoryHider::HistoryHider(MainWidget *parent) : TWidget(parent) -, _sharedContact(0) -, _forwardSelected(false) , _sendPath(true) , _send(this, lang(lng_forward_send), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) -, offered(0) , a_opacity(0, 1) , _a_appearance(animation(this, &HistoryHider::step_appearance)) -, hiding(false) -, _forwardRequest(0) -, toTextWidth(0) -, shadow(st::boxShadow) { +, _shadow(st::boxShadow) { init(); } HistoryHider::HistoryHider(MainWidget *parent, const QString &botAndQuery) : TWidget(parent) -, _sharedContact(0) -, _forwardSelected(false) -, _sendPath(false) , _botAndQuery(botAndQuery) , _send(this, lang(lng_forward_send), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) -, offered(0) , a_opacity(0, 1) , _a_appearance(animation(this, &HistoryHider::step_appearance)) -, hiding(false) -, _forwardRequest(0) -, toTextWidth(0) -, shadow(st::boxShadow) { +, _shadow(st::boxShadow) { init(); } HistoryHider::HistoryHider(MainWidget *parent, const QString &url, const QString &text) : TWidget(parent) -, _sharedContact(0) -, _forwardSelected(false) -, _sendPath(false) , _shareUrl(url) , _shareText(text) , _send(this, lang(lng_forward_send), st::defaultBoxButton) , _cancel(this, lang(lng_cancel), st::cancelBoxButton) -, offered(0) , a_opacity(0, 1) , _a_appearance(animation(this, &HistoryHider::step_appearance)) -, hiding(false) -, _forwardRequest(0) -, toTextWidth(0) -, shadow(st::boxShadow) { +, _shadow(st::boxShadow) { init(); } @@ -2736,7 +2704,7 @@ void HistoryHider::step_appearance(float64 ms, bool timer) { if (dt >= 1) { _a_appearance.stop(); a_opacity.finish(); - if (hiding) { + if (_hiding) { QTimer::singleShot(0, this, SLOT(deleteLater())); } } else { @@ -2752,45 +2720,45 @@ bool HistoryHider::withConfirm() const { void HistoryHider::paintEvent(QPaintEvent *e) { Painter p(this); - if (!hiding || !cacheForAnim.isNull() || !offered) { + if (!_hiding || !_cacheForAnim.isNull() || !_offered) { p.setOpacity(a_opacity.current() * st::layerAlpha); p.fillRect(rect(), st::layerBg->b); p.setOpacity(a_opacity.current()); } - if (cacheForAnim.isNull() || !offered) { - p.setFont(st::forwardFont->f); - if (offered) { - shadow.paint(p, box, st::boxShadowShift); + if (_cacheForAnim.isNull() || !_offered) { + p.setFont(st::forwardFont); + if (_offered) { + _shadow.paint(p, _box, st::boxShadowShift); // fill bg - p.fillRect(box, st::boxBg->b); + p.fillRect(_box, st::boxBg); - p.setPen(st::black->p); - toText.drawElided(p, box.left() + st::boxPadding.left(), box.top() + st::boxPadding.top(), toTextWidth + 2); + p.setPen(st::black); + _toText.drawElided(p, _box.left() + st::boxPadding.left(), _box.top() + st::boxPadding.top(), _toTextWidth + 2); } else { int32 w = st::forwardMargins.left() + _chooseWidth + st::forwardMargins.right(), h = st::forwardMargins.top() + st::forwardFont->height + st::forwardMargins.bottom(); App::roundRect(p, (width() - w) / 2, (height() - st::titleHeight - h) / 2, w, h, st::forwardBg, ForwardCorners); - p.setPen(st::white->p); - p.drawText(box, lang(_botAndQuery.isEmpty() ? lng_forward_choose : lng_inline_switch_choose), QTextOption(style::al_center)); + p.setPen(st::white); + p.drawText(_box, lang(_botAndQuery.isEmpty() ? lng_forward_choose : lng_inline_switch_choose), QTextOption(style::al_center)); } } else { - p.drawPixmap(box.left(), box.top(), cacheForAnim); + p.drawPixmap(_box.left(), _box.top(), _cacheForAnim); } } void HistoryHider::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { - if (offered) { - offered = 0; - resizeEvent(0); + if (_offered) { + _offered = nullptr; + resizeEvent(nullptr); update(); App::main()->dialogsActivate(); } else { startHide(); } } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) { - if (offered) { + if (_offered) { forward(); } } @@ -2798,19 +2766,19 @@ void HistoryHider::keyPressEvent(QKeyEvent *e) { void HistoryHider::mousePressEvent(QMouseEvent *e) { if (e->button() == Qt::LeftButton) { - if (!box.contains(e->pos())) { + if (!_box.contains(e->pos())) { startHide(); } } } void HistoryHider::startHide() { - if (hiding) return; - hiding = true; + if (_hiding) return; + _hiding = true; if (Adaptive::OneColumn()) { QTimer::singleShot(0, this, SLOT(deleteLater())); } else { - if (offered) cacheForAnim = myGrab(this, box); + if (_offered) _cacheForAnim = myGrab(this, _box); if (_forwardRequest) MTP::cancel(_forwardRequest); a_opacity.start(0); _send.hide(); @@ -2820,17 +2788,17 @@ void HistoryHider::startHide() { } void HistoryHider::forward() { - if (!hiding && offered) { + if (!_hiding && _offered) { if (_sharedContact) { - parent()->onShareContact(offered->id, _sharedContact); + parent()->onShareContact(_offered->id, _sharedContact); } else if (_sendPath) { - parent()->onSendPaths(offered->id); + parent()->onSendPaths(_offered->id); } else if (!_shareUrl.isEmpty()) { - parent()->onShareUrl(offered->id, _shareUrl, _shareText); + parent()->onShareUrl(_offered->id, _shareUrl, _shareText); } else if (!_botAndQuery.isEmpty()) { - parent()->onInlineSwitchChosen(offered->id, _botAndQuery); + parent()->onInlineSwitchChosen(_offered->id, _botAndQuery); } else { - parent()->onForward(offered->id, _forwardSelected ? ForwardSelectedMessages : ForwardContextMessage); + parent()->onForward(_offered->id, _forwardSelected ? ForwardSelectedMessages : ForwardContextMessage); } } emit forwarded(); @@ -2847,8 +2815,8 @@ MainWidget *HistoryHider::parent() { void HistoryHider::resizeEvent(QResizeEvent *e) { int32 w = st::boxWidth, h = st::boxPadding.top() + st::boxPadding.bottom(); - if (offered) { - if (!hiding) { + if (_offered) { + if (!_hiding) { _send.show(); _cancel.show(); } @@ -2858,22 +2826,22 @@ void HistoryHider::resizeEvent(QResizeEvent *e) { _send.hide(); _cancel.hide(); } - box = QRect((width() - w) / 2, (height() - st::titleHeight - h) / 2, w, h); - _send.moveToRight(width() - (box.x() + box.width()) + st::boxButtonPadding.right(), box.y() + h - st::boxButtonPadding.bottom() - _send.height()); - _cancel.moveToRight(width() - (box.x() + box.width()) + st::boxButtonPadding.right() + _send.width() + st::boxButtonPadding.left(), _send.y()); + _box = QRect((width() - w) / 2, (height() - st::titleHeight - h) / 2, w, h); + _send.moveToRight(width() - (_box.x() + _box.width()) + st::boxButtonPadding.right(), _box.y() + h - st::boxButtonPadding.bottom() - _send.height()); + _cancel.moveToRight(width() - (_box.x() + _box.width()) + st::boxButtonPadding.right() + _send.width() + st::boxButtonPadding.left(), _send.y()); } bool HistoryHider::offerPeer(PeerId peer) { if (!peer) { - offered = 0; - toText.setText(st::boxTextFont, QString()); - toTextWidth = 0; - resizeEvent(0); + _offered = nullptr; + _toText.setText(st::boxTextFont, QString()); + _toTextWidth = 0; + resizeEvent(nullptr); return false; } - offered = App::peer(peer); + _offered = App::peer(peer); LangString phrase; - QString recipient = offered->isUser() ? offered->name : '\xAB' + offered->name + '\xBB'; + QString recipient = _offered->isUser() ? _offered->name : '\xAB' + _offered->name + '\xBB'; if (_sharedContact) { phrase = lng_forward_share_contact(lt_recipient, recipient); } else if (_sendPath) { @@ -2887,35 +2855,35 @@ bool HistoryHider::offerPeer(PeerId peer) { phrase = lng_forward_send_file_confirm(lt_name, name, lt_recipient, recipient); } } else if (!_shareUrl.isEmpty()) { - PeerId to = offered->id; - offered = 0; + PeerId to = _offered->id; + _offered = nullptr; if (parent()->onShareUrl(to, _shareUrl, _shareText)) { startHide(); } return false; } else if (!_botAndQuery.isEmpty()) { - PeerId to = offered->id; - offered = 0; + PeerId to = _offered->id; + _offered = nullptr; if (parent()->onInlineSwitchChosen(to, _botAndQuery)) { startHide(); } return false; } else { - PeerId to = offered->id; - offered = 0; + PeerId to = _offered->id; + _offered = nullptr; if (parent()->onForward(to, _forwardSelected ? ForwardSelectedMessages : ForwardContextMessage)) { startHide(); } return false; } - toText.setText(st::boxTextFont, phrase, _textNameOptions); - toTextWidth = toText.maxWidth(); - if (toTextWidth > box.width() - st::boxPadding.left() - st::boxButtonPadding.right()) { - toTextWidth = box.width() - st::boxPadding.left() - st::boxButtonPadding.right(); + _toText.setText(st::boxTextFont, phrase, _textNameOptions); + _toTextWidth = _toText.maxWidth(); + if (_toTextWidth > _box.width() - st::boxPadding.left() - st::boxButtonPadding.right()) { + _toTextWidth = _box.width() - st::boxPadding.left() - st::boxButtonPadding.right(); } - resizeEvent(0); + resizeEvent(nullptr); update(); setFocus(); @@ -2923,11 +2891,11 @@ bool HistoryHider::offerPeer(PeerId peer) { } QString HistoryHider::offeredText() const { - return toText.originalText(); + return _toText.originalText(); } bool HistoryHider::wasOffered() const { - return !!offered; + return _offered != nullptr; } HistoryHider::~HistoryHider() { @@ -3404,7 +3372,7 @@ void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraf } } - if (!_editMsgId) { + if (!_editMsgId && !_inlineBot) { _saveCloudDraftTimer.start(SaveCloudDraftIdleTimeout); } } @@ -6017,7 +5985,6 @@ bool HistoryWidget::hasSilentToggle() const { void HistoryWidget::inlineBotResolveDone(const MTPcontacts_ResolvedPeer &result) { _inlineBotResolveRequestId = 0; // Notify::inlineBotRequesting(false); - _inlineBotUsername = QString(); UserData *resolvedBot = nullptr; if (result.type() == mtpc_contacts_resolvedPeer) { const auto &d(result.c_contacts_resolvedPeer()); @@ -8895,6 +8862,6 @@ bool HistoryWidget::touchScroll(const QPoint &delta) { } HistoryWidget::~HistoryWidget() { - deleteAndMark(_pinnedBar); - deleteAndMark(_list); + delete base::take(_pinnedBar); + delete base::take(_list); } diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index ab8d8282c8..af7d4e4d58 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -21,10 +21,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "localimageloader.h" -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" +#include "ui/popupmenu.h" #include "history/history_common.h" #include "history/field_autocomplete.h" #include "window/section_widget.h" +#include "core/single_timer.h" namespace InlineBots { namespace Layout { @@ -479,30 +481,31 @@ private: void init(); MainWidget *parent(); - UserData *_sharedContact; - bool _forwardSelected, _sendPath; + UserData *_sharedContact = nullptr; + bool _forwardSelected = false; + bool _sendPath = false; QString _shareUrl, _shareText; QString _botAndQuery; BoxButton _send, _cancel; - PeerData *offered; + PeerData *_offered = nullptr; anim::fvalue a_opacity; Animation _a_appearance; - QRect box; - bool hiding; + QRect _box; + bool _hiding = false; - mtpRequestId _forwardRequest; + mtpRequestId _forwardRequest = 0; - int32 _chooseWidth; + int _chooseWidth = 0; - Text toText; - int32 toTextWidth; - QPixmap cacheForAnim; + Text _toText; + int32 _toTextWidth = 0; + QPixmap _cacheForAnim; - BoxShadow shadow; + Ui::RectShadow _shadow; }; diff --git a/Telegram/SourceFiles/lang.h b/Telegram/SourceFiles/lang.h index 4202e78451..e8e551900a 100644 --- a/Telegram/SourceFiles/lang.h +++ b/Telegram/SourceFiles/lang.h @@ -29,7 +29,7 @@ constexpr const str_const LanguageCodes[] = { "pt_BR", "ko", }; -constexpr const int languageTest = -1, languageDefault = 0, languageCount = arraysize(LanguageCodes); +constexpr const int languageTest = -1, languageDefault = 0, languageCount = base::array_size(LanguageCodes); class LangString : public QString { public: diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 700ea01747..ca803e083e 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -83,7 +83,7 @@ private: QRect _box, _hiddenSpecialBox; float64 _opacity = 0.; - BoxShadow _shadow; + Ui::RectShadow _shadow; }; diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h index ff6a668e62..8e0585547b 100644 --- a/Telegram/SourceFiles/layerwidget.h +++ b/Telegram/SourceFiles/layerwidget.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" class LayerWidget : public TWidget { Q_OBJECT diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 14f41d94ae..a57e4f56ed 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -32,6 +32,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwindow.h" #include "lang.h" #include "media/media_audio.h" +#include "application.h" #include "apiwrap.h" namespace Local { @@ -534,7 +535,7 @@ enum { dbiDcOption = 0x27, dbiTryIPv6 = 0x28, dbiSongVolume = 0x29, - dbiWindowsNotifications = 0x30, + dbiWindowsNotificationsOld = 0x30, dbiIncludeMuted = 0x31, dbiMegagroupSizeMax = 0x32, dbiDownloadPath = 0x33, @@ -548,6 +549,9 @@ enum { dbiModerateMode = 0x41, dbiVideoVolume = 0x42, dbiStickersRecentLimit = 0x43, + dbiNativeNotifications = 0x44, + dbiNotificationsCount = 0x45, + dbiNotificationsCorner = 0x46, dbiEncryptedWithSalt = 333, dbiEncrypted = 444, @@ -989,15 +993,34 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) { if (App::wnd()) App::wnd()->updateTrayMenu(); } break; - case dbiWindowsNotifications: { + case dbiWindowsNotificationsOld: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + } break; + + case dbiNativeNotifications: { qint32 v; stream >> v; if (!_checkStreamStatus(stream)) return false; - Global::SetWindowsNotifications(v == 1); - if (cPlatform() == dbipWindows) { - Global::SetCustomNotifies((App::wnd() ? !App::wnd()->psHasNativeNotifications() : true) || !Global::WindowsNotifications()); - } + Global::SetNativeNotifications(v == 1); + } break; + + case dbiNotificationsCount: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + Global::SetNotificationsCount((v > 0 ? v : 3)); + } break; + + case dbiNotificationsCorner: { + qint32 v; + stream >> v; + if (!_checkStreamStatus(stream)) return false; + + Global::SetNotificationsCorner(static_cast((v >= 0 && v < 4) ? v : 2)); } break; case dbiWorkMode: { @@ -1056,6 +1079,9 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) { if (!_checkStreamStatus(stream)) return false; cSetAutoUpdate(v == 1); + if (!cAutoUpdate()) { + Sandbox::stopUpdate(); + } } break; case dbiLastUpdateCheck: { @@ -1568,7 +1594,7 @@ void _writeUserSettings() { _writeMap(WriteMapFast); } - uint32 size = 18 * (sizeof(quint32) + sizeof(qint32)); + uint32 size = 20 * (sizeof(quint32) + sizeof(qint32)); size += sizeof(quint32) + Serialize::stringSize(Global::AskDownloadPath() ? QString() : Global::DownloadPath()) + Serialize::bytearraySize(Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark()); size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort)); size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64)); @@ -1592,7 +1618,9 @@ void _writeUserSettings() { data.stream << quint32(dbiShowingSavedGifs) << qint32(cShowingSavedGifs()); data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify()); data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView()); - data.stream << quint32(dbiWindowsNotifications) << qint32(Global::WindowsNotifications()); + data.stream << quint32(dbiNativeNotifications) << qint32(Global::NativeNotifications()); + data.stream << quint32(dbiNotificationsCount) << qint32(Global::NotificationsCount()); + data.stream << quint32(dbiNotificationsCorner) << qint32(Global::NotificationsCorner()); data.stream << quint32(dbiAskDownloadPath) << qint32(Global::AskDownloadPath()); data.stream << quint32(dbiDownloadPath) << (Global::AskDownloadPath() ? QString() : Global::DownloadPath()) << (Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark()); data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage()); @@ -2627,7 +2655,7 @@ public: virtual void readFromStream(QDataStream &stream, quint64 &first, quint64 &second, quint32 &type, QByteArray &data) = 0; virtual void clearInMap() = 0; virtual ~AbstractCachedLoadTask() { - deleteAndMark(_result); + delete base::take(_result); } protected: @@ -2903,7 +2931,7 @@ public: } } virtual ~WebFileLoadTask() { - deleteAndMark(_result); + delete base::take(_result); } protected: diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index fd83ba4220..5565cecbd3 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -1015,8 +1015,7 @@ namespace internal { #if !defined Q_OS_MAC || defined MAC_USE_BREAKPAD if (internal::BreakpadExceptionHandler) { - google_breakpad::ExceptionHandler *h = getPointerAndReset(internal::BreakpadExceptionHandler); - delete h; + delete base::take(internal::BreakpadExceptionHandler); } #endif // !Q_OS_MAC || MAC_USE_BREAKPAD diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b5151ab03d..b265b3d7b7 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -3324,10 +3324,7 @@ void MainWidget::start(const MTPUser &user) { App::feedUsers(MTP_vector(1, user)); MTP::send(MTPupdates_GetState(), rpcDone(&MainWidget::gotState)); update(); - if (!cStartUrl().isEmpty()) { - openLocalUrl(cStartUrl()); - cSetStartUrl(QString()); - } + _started = true; App::wnd()->sendServiceHistoryRequest(); Local::readInstalledStickers(); @@ -3335,12 +3332,23 @@ void MainWidget::start(const MTPUser &user) { Local::readRecentStickers(); Local::readSavedGifs(); _history->start(); + + checkStartUrl(); } bool MainWidget::started() { return _started; } +void MainWidget::checkStartUrl() { + if (!cStartUrl().isEmpty() && App::self() && !App::passcoded()) { + auto url = cStartUrl(); + cSetStartUrl(QString()); + + openLocalUrl(url); + } +} + void MainWidget::openLocalUrl(const QString &url) { auto urlTrimmed = url.trimmed(); if (urlTrimmed.size() > 8192) urlTrimmed = urlTrimmed.mid(0, 8192); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 5ac2087a36..1a7be86a09 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localimageloader.h" #include "history/history_common.h" +#include "core/single_timer.h" namespace Dialogs { class Row; @@ -156,6 +157,7 @@ public: void start(const MTPUser &user); + void checkStartUrl(); void openLocalUrl(const QString &str); void openPeerByName(const QString &name, MsgId msgId = ShowAtUnreadMsgId, const QString &startToken = QString()); void joinGroupByHash(const QString &hash); diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 56129b5dc8..8b4001dad0 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dialogs/dialogs_layout.h" #include "styles/style_dialogs.h" +#include "ui/popupmenu.h" #include "zip.h" #include "lang.h" #include "shortcuts.h" @@ -42,8 +43,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" #include "apiwrap.h" #include "settings/settings_widget.h" +#include "window/notifications_manager.h" -ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : QWidget(parent), _shadow(st::boxShadow), _reconnect(this, QString()) { +ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : QWidget(parent) +, _shadow(st::boxShadow) +, _reconnect(this, QString()) { set(text, reconnect); connect(&_reconnect, SIGNAL(clicked()), this, SLOT(onReconnect())); } @@ -57,310 +61,27 @@ void ConnectingWidget::set(const QString &text, const QString &reconnect) { } else { _reconnect.setText(reconnect); _reconnect.show(); - _reconnect.move(st::connectingPadding.left() + _textWidth, st::boxShadow.pxHeight() + st::connectingPadding.top()); + _reconnect.move(st::connectingPadding.left() + _textWidth, st::boxShadow.height() + st::connectingPadding.top()); _reconnectWidth = _reconnect.width(); } - resize(st::connectingPadding.left() + _textWidth + _reconnectWidth + st::connectingPadding.right() + st::boxShadow.pxWidth(), st::boxShadow.pxHeight() + st::connectingPadding.top() + st::linkFont->height + st::connectingPadding.bottom()); + resize(st::connectingPadding.left() + _textWidth + _reconnectWidth + st::connectingPadding.right() + st::boxShadow.width(), st::boxShadow.height() + st::connectingPadding.top() + st::linkFont->height + st::connectingPadding.bottom()); update(); } void ConnectingWidget::paintEvent(QPaintEvent *e) { - QPainter p(this); + Painter p(this); - _shadow.paint(p, QRect(0, st::boxShadow.pxHeight(), width() - st::boxShadow.pxWidth(), height() - st::boxShadow.pxHeight()), 0, BoxShadow::Top | BoxShadow::Right); - p.fillRect(0, st::boxShadow.pxHeight(), width() - st::boxShadow.pxWidth(), height() - st::boxShadow.pxHeight(), st::connectingBG->b); + _shadow.paint(p, QRect(0, st::boxShadow.height(), width() - st::boxShadow.width(), height() - st::boxShadow.height()), 0, Ui::RectShadow::Side::Top | Ui::RectShadow::Side::Right); + p.fillRect(0, st::boxShadow.height(), width() - st::boxShadow.width(), height() - st::boxShadow.height(), st::connectingBG->b); p.setFont(st::linkFont->f); p.setPen(st::connectingColor->p); - p.drawText(st::connectingPadding.left(), st::boxShadow.pxHeight() + st::connectingPadding.top() + st::linkFont->ascent, _text); + p.drawText(st::connectingPadding.left(), st::boxShadow.height() + st::connectingPadding.top() + st::linkFont->ascent, _text); } void ConnectingWidget::onReconnect() { MTP::restart(); } -NotifyWindow::NotifyWindow(HistoryItem *msg, int32 x, int32 y, int32 fwdCount) : TWidget(0) -, history(msg->history()) -, item(msg) -, fwdCount(fwdCount) -#if defined Q_OS_WIN && !defined Q_OS_WINRT -, started(GetTickCount()) -#endif // Q_OS_WIN && !Q_OS_WINRT -, close(this, st::notifyClose) -, alphaDuration(st::notifyFastAnim) -, posDuration(st::notifyFastAnim) -, hiding(false) -, _index(0) -, a_opacity(0) -, a_func(anim::linear) -, a_y(y + st::notifyHeight + st::notifyDeltaY) -, _a_appearance(animation(this, &NotifyWindow::step_appearance)) { - - updateNotifyDisplay(); - - hideTimer.setSingleShot(true); - connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); - - inputTimer.setSingleShot(true); - connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); - - connect(&close, SIGNAL(clicked()), this, SLOT(unlinkHistoryAndNotify())); - close.setAcceptBoth(true); - close.move(st::notifyWidth - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); - close.show(); - - a_y.start(y); - setGeometry(x, a_y.current(), st::notifyWidth, st::notifyHeight); - - a_opacity.start(1); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); - setAttribute(Qt::WA_MacAlwaysShowToolWindow); - - show(); - - setWindowOpacity(a_opacity.current()); - - alphaDuration = posDuration = st::notifyFastAnim; - _a_appearance.start(); - - checkLastInput(); -} - -void NotifyWindow::checkLastInput() { -#if defined Q_OS_WIN && !defined Q_OS_WINRT - LASTINPUTINFO lii; - lii.cbSize = sizeof(LASTINPUTINFO); - BOOL res = GetLastInputInfo(&lii); - if (!res || lii.dwTime >= started) { - hideTimer.start(st::notifyWaitLongHide); - } else { - inputTimer.start(300); - } -#else // Q_OS_WIN && !Q_OS_WINRT - // TODO - if (true) { - hideTimer.start(st::notifyWaitLongHide); - } else { - inputTimer.start(300); - } -#endif // else for Q_OS_WIN && !Q_OS_WINRT -} - -void NotifyWindow::moveTo(int32 x, int32 y, int32 index) { - if (index >= 0) { - _index = index; - } - move(x, a_y.current()); - a_y.start(y); - a_opacity.restart(); - posDuration = st::notifyFastAnim; - _a_appearance.start(); -} - -void NotifyWindow::updateNotifyDisplay() { - if (!item) return; - - int32 w = st::notifyWidth, h = st::notifyHeight; - QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); - if (cRetina()) img.setDevicePixelRatio(cRetinaFactor()); - img.fill(st::notifyBG->c); - - { - Painter p(&img); - p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder->b); - p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder->b); - - if (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { - history->peer->loadUserpic(true, true); - history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); - } else { - static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon); - } - - int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; - - QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); - if (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { - if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(history->peer, false)) { - chatTypeIcon->paint(p, rectForName.topLeft(), w); - rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); - } - } - - QDateTime now(QDateTime::currentDateTime()), lastTime(item->date); - QDate nowDate(now.date()), lastDate(lastTime.date()); - QString dt = lastTime.toString(cTimeFormat()); - int32 dtWidth = st::dialogsTextFont->width(dt); - rectForName.setWidth(rectForName.width() - dtWidth - st::dialogsDateSkip); - p.setFont(st::dialogsDateFont); - p.setPen(st::dialogsDateFg); - p.drawText(rectForName.left() + rectForName.width() + st::dialogsDateSkip, rectForName.top() + st::dialogsTextFont->ascent, dt); - - if (!App::passcoded() && Global::NotifyView() <= dbinvShowPreview) { - const HistoryItem *textCachedFor = 0; - Text itemTextCache(itemWidth); - QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height); - if (fwdCount < 2) { - bool active = false; - item->drawInDialog(p, r, active, textCachedFor, itemTextCache); - } else { - p.setFont(st::dialogsTextFont); - if (item->hasFromName() && !item->isPost()) { - itemTextCache.setText(st::dialogsTextFont, item->author()->name); - p.setPen(st::dialogsTextFgService); - itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dialogsTextFont->height); - r.setTop(r.top() + st::dialogsTextFont->height); - } - p.setPen(st::dialogsTextFg); - p.drawText(r.left(), r.top() + st::dialogsTextFont->ascent, lng_forward_messages(lt_count, fwdCount)); - } - } else { - static QString notifyText = st::dialogsTextFont->elided(lang(lng_notification_preview), itemWidth); - p.setPen(st::dialogsTextFgService); - p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText); - } - - p.setPen(st::dialogsNameFg); - if (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { - history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); - } else { - p.setFont(st::msgNameFont->f); - static QString notifyTitle = st::msgNameFont->elided(qsl("Telegram Desktop"), rectForName.width()); - p.drawText(rectForName.left(), rectForName.top() + st::msgNameFont->ascent, notifyTitle); - } - } - - pm = App::pixmapFromImageInPlace(std_::move(img)); - update(); -} - -void NotifyWindow::updatePeerPhoto() { - if (!peerPhoto->isNull() && peerPhoto->loaded()) { - QImage img(pm.toImage()); - { - QPainter p(&img); - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); - } - peerPhoto = ImagePtr(); - pm = App::pixmapFromImageInPlace(std_::move(img)); - update(); - } -} - -void NotifyWindow::itemRemoved(HistoryItem *del) { - if (item == del) { - item = 0; - unlinkHistoryAndNotify(); - } -} - -void NotifyWindow::unlinkHistoryAndNotify() { - unlinkHistory(); - App::wnd()->notifyShowNext(); -} - -void NotifyWindow::unlinkHistory(History *hist) { - if (!hist || hist == history) { - animHide(st::notifyFastAnim, anim::linear); - history = 0; - item = 0; - } -} - -void NotifyWindow::enterEvent(QEvent *e) { - if (!history) return; - if (App::wnd()) App::wnd()->notifyStopHiding(); -} - -void NotifyWindow::leaveEvent(QEvent *e) { - if (!history) return; - App::wnd()->notifyStartHiding(); -} - -void NotifyWindow::startHiding() { - hideTimer.start(st::notifyWaitShortHide); -} - -void NotifyWindow::mousePressEvent(QMouseEvent *e) { - if (!history) return; - - PeerId peer = history->peer->id; - MsgId msgId = (!history->peer->isUser() && item && item->mentionsMe() && item->id > 0) ? item->id : ShowAtUnreadMsgId; - - if (e->button() == Qt::RightButton) { - unlinkHistoryAndNotify(); - } else { - App::wnd()->showFromTray(); - if (App::passcoded()) { - App::wnd()->setInnerFocus(); - App::wnd()->notifyClear(); - } else { - Ui::showPeerHistory(peer, msgId); - } - e->ignore(); - } -} - -void NotifyWindow::paintEvent(QPaintEvent *e) { - QPainter p(this); - p.drawPixmap(0, 0, pm); -} - -void NotifyWindow::animHide(float64 duration, anim::transition func) { - if (!history) return; - alphaDuration = duration; - a_func = func; - a_opacity.start(0); - a_y.restart(); - hiding = true; - _a_appearance.start(); -} - -void NotifyWindow::stopHiding() { - if (!history) return; - alphaDuration = st::notifyFastAnim; - a_func = anim::linear; - a_opacity.start(1); - a_y.restart(); - hiding = false; - hideTimer.stop(); - _a_appearance.start(); -} - -void NotifyWindow::hideByTimer() { - if (!history) return; - animHide(st::notifySlowHide, st::notifySlowHideFunc); -} - -void NotifyWindow::step_appearance(float64 ms, bool timer) { - float64 dtAlpha = ms / alphaDuration, dtPos = ms / posDuration; - if (dtAlpha >= 1) { - a_opacity.finish(); - if (hiding) { - _a_appearance.stop(); - deleteLater(); - } else if (dtPos >= 1) { - _a_appearance.stop(); - } - } else { - a_opacity.update(dtAlpha, a_func); - } - setWindowOpacity(a_opacity.current()); - if (dtPos >= 1) { - a_y.finish(); - } else { - a_y.update(dtPos, anim::linear); - } - move(x(), a_y.current()); - update(); -} - -NotifyWindow::~NotifyWindow() { - if (App::wnd()) App::wnd()->notifyShowNext(this); -} - MainWindow::MainWindow() { icon16 = icon256.scaledToWidth(16, Qt::SmoothTransformation); icon32 = icon256.scaledToWidth(32, Qt::SmoothTransformation); @@ -375,8 +96,6 @@ MainWindow::MainWindow() { notifyClear(); } else if (type == Notify::ChangeType::ViewParams) { notifyUpdateAll(); - } else if (type == Notify::ChangeType::UseNative) { - notifyClearFast(); } else if (type == Notify::ChangeType::IncludeMuted) { Notify::unreadCounterUpdated(); } @@ -397,14 +116,13 @@ MainWindow::MainWindow() { _inactiveTimer.setSingleShot(true); connect(&_inactiveTimer, SIGNAL(timeout()), this, SLOT(onInactiveTimer())); - connect(¬ifyWaitTimer, SIGNAL(timeout()), this, SLOT(notifyFire())); + connect(&_notifyWaitTimer, SIGNAL(timeout()), this, SLOT(notifyShowNext())); _isActiveTimer.setSingleShot(true); connect(&_isActiveTimer, SIGNAL(timeout()), this, SLOT(updateIsActive())); connect(&_autoLockTimer, SIGNAL(timeout()), this, SLOT(checkAutoLock())); - subscribe(FileDownload::ImageLoaded(), [this] { notifyUpdateAllPhotos(); }); subscribe(Global::RefSelfChanged(), [this]() { updateGlobalMenu(); }); setAttribute(Qt::WA_NoSystemBackground); @@ -547,6 +265,10 @@ void MainWindow::clearPasscode() { notifyUpdateAll(); title->updateControlsVisibility(); updateGlobalMenu(); + + if (auto main = App::main()) { + main->checkStartUrl(); + } } void MainWindow::setupPasscode(bool anim) { @@ -1030,9 +752,8 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) { QString url = static_cast(e)->url().toEncoded().trimmed(); if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) { cSetStartUrl(url.mid(0, 8192)); - if (!cStartUrl().isEmpty() && App::main() && App::self()) { - App::main()->openLocalUrl(cStartUrl()); - cSetStartUrl(QString()); + if (auto main = App::main()) { + main->checkStartUrl(); } } activate(); @@ -1402,72 +1123,66 @@ void MainWindow::notifySchedule(History *history, HistoryItem *item) { // LOG(("Is online: %1, otherOnline: %2, currentTime: %3, otherNotOld: %4, otherLaterThanMe: %5").arg(Logs::b(isOnline)).arg(cOtherOnline()).arg(t).arg(Logs::b(otherNotOld)).arg(Logs::b(otherLaterThanMe))); uint64 when = ms + delay; - notifyWhenAlerts[history].insert(when, notifyByFrom); + _notifyWhenAlerts[history].insert(when, notifyByFrom); if (Global::DesktopNotify() && !psSkipDesktopNotify()) { - NotifyWhenMaps::iterator i = notifyWhenMaps.find(history); - if (i == notifyWhenMaps.end()) { - i = notifyWhenMaps.insert(history, NotifyWhenMap()); + NotifyWhenMaps::iterator i = _notifyWhenMaps.find(history); + if (i == _notifyWhenMaps.end()) { + i = _notifyWhenMaps.insert(history, NotifyWhenMap()); } if (i.value().constFind(item->id) == i.value().cend()) { i.value().insert(item->id, when); } - NotifyWaiters *addTo = haveSetting ? ¬ifyWaiters : ¬ifySettingWaiters; + NotifyWaiters *addTo = haveSetting ? &_notifyWaiters : &_notifySettingWaiters; NotifyWaiters::const_iterator it = addTo->constFind(history); if (it == addTo->cend() || it->when > when) { addTo->insert(history, NotifyWaiter(item->id, when, notifyByFrom)); } } if (haveSetting) { - if (!notifyWaitTimer.isActive() || notifyWaitTimer.remainingTime() > delay) { - notifyWaitTimer.start(delay); + if (!_notifyWaitTimer.isActive() || _notifyWaitTimer.remainingTime() > delay) { + _notifyWaitTimer.start(delay); } } } -void MainWindow::notifyFire() { - notifyShowNext(); -} - void MainWindow::notifyClear(History *history) { if (!history) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(); - } - psClearNotifies(); - for (NotifyWhenMaps::const_iterator i = notifyWhenMaps.cbegin(), e = notifyWhenMaps.cend(); i != e; ++i) { + Window::Notifications::manager()->clearAll(); + + for (auto i = _notifyWhenMaps.cbegin(), e = _notifyWhenMaps.cend(); i != e; ++i) { i.key()->clearNotifications(); } - notifyWaiters.clear(); - notifySettingWaiters.clear(); - notifyWhenMaps.clear(); + _notifyWhenMaps.clear(); + _notifyWhenAlerts.clear(); + _notifyWaiters.clear(); + _notifySettingWaiters.clear(); return; } - notifyWaiters.remove(history); - notifySettingWaiters.remove(history); - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(history); - } - psClearNotifies(history->peer->id); - notifyWhenMaps.remove(history); - notifyWhenAlerts.remove(history); + + Window::Notifications::manager()->clearFromHistory(history); + + history->clearNotifications(); + _notifyWhenMaps.remove(history); + _notifyWhenAlerts.remove(history); + _notifyWaiters.remove(history); + _notifySettingWaiters.remove(history); + + _notifyWaitTimer.stop(); notifyShowNext(); } void MainWindow::notifyClearFast() { - notifyWaiters.clear(); - notifySettingWaiters.clear(); - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->deleteLater(); - } - psClearNotifies(); - notifyWindows.clear(); - notifyWhenMaps.clear(); - notifyWhenAlerts.clear(); + Window::Notifications::manager()->clearAllFast(); + + _notifyWhenMaps.clear(); + _notifyWhenAlerts.clear(); + _notifyWaiters.clear(); + _notifySettingWaiters.clear(); } void MainWindow::notifySettingGot() { int32 t = unixtime(); - for (NotifyWaiters::iterator i = notifySettingWaiters.begin(); i != notifySettingWaiters.end();) { + for (NotifyWaiters::iterator i = _notifySettingWaiters.begin(); i != _notifySettingWaiters.end();) { History *history = i.key(); bool loaded = false, muted = false; if (history->peer->notify != UnknownNotifySettings) { @@ -1496,34 +1211,24 @@ void MainWindow::notifySettingGot() { } if (loaded) { if (!muted) { - notifyWaiters.insert(i.key(), i.value()); + _notifyWaiters.insert(i.key(), i.value()); } - i = notifySettingWaiters.erase(i); + i = _notifySettingWaiters.erase(i); } else { ++i; } } - notifyWaitTimer.stop(); + _notifyWaitTimer.stop(); notifyShowNext(); } -void MainWindow::notifyShowNext(NotifyWindow *remove) { +void MainWindow::notifyShowNext() { if (App::quitting()) return; - int32 count = NotifyWindowsCount; - if (remove) { - for (NotifyWindows::iterator i = notifyWindows.begin(), e = notifyWindows.end(); i != e; ++i) { - if ((*i) == remove) { - notifyWindows.erase(i); - break; - } - } - } - uint64 ms = getms(true), nextAlert = 0; bool alert = false; int32 now = unixtime(); - for (NotifyWhenAlerts::iterator i = notifyWhenAlerts.begin(); i != notifyWhenAlerts.end();) { + for (NotifyWhenAlerts::iterator i = _notifyWhenAlerts.begin(); i != _notifyWhenAlerts.end();) { while (!i.value().isEmpty() && i.value().begin().key() <= ms) { NotifySettingsPtr n = i.key()->peer->notify, f = i.value().begin().value() ? i.value().begin().value()->notify : UnknownNotifySettings; while (!i.value().isEmpty() && i.value().begin().key() <= ms + 500) { // not more than one sound in 500ms from one peer - grouping @@ -1536,7 +1241,7 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } } if (i.value().isEmpty()) { - i = notifyWhenAlerts.erase(i); + i = _notifyWhenAlerts.erase(i); } else { if (!nextAlert || nextAlert > i.value().begin().key()) { nextAlert = i.value().begin().key(); @@ -1549,33 +1254,24 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { App::playSound(); } - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - } - } - if (count <= 0 || notifyWaiters.isEmpty() || !Global::DesktopNotify() || psSkipDesktopNotify()) { + if (_notifyWaiters.isEmpty() || !Global::DesktopNotify() || psSkipDesktopNotify()) { if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); + _notifyWaitTimer.start(nextAlert - ms); } return; } - QRect r = psDesktopRect(); - int32 x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX, y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY; - while (count > 0) { + while (true) { uint64 next = 0; HistoryItem *notifyItem = 0; History *notifyHistory = 0; - for (NotifyWaiters::iterator i = notifyWaiters.begin(); i != notifyWaiters.end();) { + for (NotifyWaiters::iterator i = _notifyWaiters.begin(); i != _notifyWaiters.end();) { History *history = i.key(); if (history->currentNotification() && history->currentNotification()->id != i.value().msg) { - NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - if (j == notifyWhenMaps.end()) { + NotifyWhenMaps::iterator j = _notifyWhenMaps.find(history); + if (j == _notifyWhenMaps.end()) { history->clearNotifications(); - i = notifyWaiters.erase(i); + i = _notifyWaiters.erase(i); continue; } do { @@ -1589,8 +1285,8 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } while (history->currentNotification()); } if (!history->currentNotification()) { - notifyWhenMaps.remove(history); - i = notifyWaiters.erase(i); + _notifyWhenMaps.remove(history); + i = _notifyWaiters.erase(i); continue; } uint64 when = i.value().when; @@ -1607,7 +1303,7 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { next = nextAlert; nextAlert = 0; } - notifyWaitTimer.start(next - ms); + _notifyWaitTimer.start(next - ms); break; } else { HistoryItem *fwd = notifyItem->Has() ? notifyItem : nullptr; // forwarded notify grouping @@ -1615,8 +1311,8 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { uint64 ms = getms(true); History *history = notifyItem->history(); - NotifyWhenMaps::iterator j = notifyWhenMaps.find(history); - if (j == notifyWhenMaps.cend()) { + NotifyWhenMaps::iterator j = _notifyWhenMaps.find(history); + if (j == _notifyWhenMaps.cend()) { history->clearNotifications(); } else { HistoryItem *nextNotify = 0; @@ -1631,7 +1327,7 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { NotifyWhenMap::const_iterator k = j.value().constFind(history->currentNotification()->id); if (k != j.value().cend()) { nextNotify = history->currentNotification(); - notifyWaiters.insert(notifyHistory, NotifyWaiter(k.key(), k.value(), 0)); + _notifyWaiters.insert(notifyHistory, NotifyWaiter(k.key(), k.value(), 0)); break; } history->skipNotification(); @@ -1652,18 +1348,11 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } while (nextNotify); } - if (Global::CustomNotifies()) { - NotifyWindow *notify = new NotifyWindow(notifyItem, x, y, fwdCount); - notifyWindows.push_back(notify); - psNotifyShown(notify); - --count; - } else { - psPlatformNotify(notifyItem, fwdCount); - } + Window::Notifications::manager()->showNotification(notifyItem, fwdCount); if (!history->hasNotification()) { - notifyWaiters.remove(history); - notifyWhenMaps.remove(history); + _notifyWaiters.remove(history); + _notifyWhenMaps.remove(history); continue; } } @@ -1672,49 +1361,8 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } } if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); + _notifyWaitTimer.start(nextAlert - ms); } - - count = NotifyWindowsCount - count; - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; - --count; - (*i)->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); - } -} - -void MainWindow::notifyItemRemoved(HistoryItem *item) { - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->itemRemoved(item); - } - } -} - -void MainWindow::notifyStopHiding() { - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->stopHiding(); - } - } -} - -void MainWindow::notifyStartHiding() { - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->startHiding(); - } - } -} - -void MainWindow::notifyUpdateAllPhotos() { - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->updatePeerPhoto(); - } - } - if (_mediaView && !_mediaView->isHidden()) _mediaView->updateControls(); } void MainWindow::app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) { @@ -1722,20 +1370,7 @@ void MainWindow::app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButt } void MainWindow::notifyUpdateAll() { - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->updateNotifyDisplay(); - } - } - psClearNotifies(); -} - -void MainWindow::notifyActivateAll() { - if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - psActivateNotify(*i); - } - } + Window::Notifications::manager()->updateAll(); } QImage MainWindow::iconLarge() const { diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index cd289b8981..144d6fb0f1 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -22,8 +22,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "title.h" #include "pspecific.h" -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" #include "platform/platform_main_window.h" +#include "core/single_timer.h" class MediaView; class TitleWidget; @@ -32,9 +33,11 @@ class IntroWidget; class MainWidget; class LayerStackWidget; class LayerWidget; + namespace Local { class ClearManager; } // namespace Local + namespace Settings { class Widget; } // namespace Settings @@ -43,87 +46,21 @@ class ConnectingWidget : public QWidget { Q_OBJECT public: - ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect); void set(const QString &text, const QString &reconnect); void paintEvent(QPaintEvent *e); public slots: - void onReconnect(); private: - - BoxShadow _shadow; + Ui::RectShadow _shadow; QString _text; int32 _textWidth; LinkButton _reconnect; }; -class NotifyWindow : public TWidget { - Q_OBJECT - -public: - - NotifyWindow(HistoryItem *item, int32 x, int32 y, int32 fwdCount); - - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); - void mousePressEvent(QMouseEvent *e); - void paintEvent(QPaintEvent *e); - - void step_appearance(float64 ms, bool timer); - void animHide(float64 duration, anim::transition func); - void startHiding(); - void stopHiding(); - void moveTo(int32 x, int32 y, int32 index = -1); - - void updateNotifyDisplay(); - void updatePeerPhoto(); - - void itemRemoved(HistoryItem *del); - - int32 index() const { - return history ? _index : -1; - } - - void unlinkHistory(History *hist = 0); - - ~NotifyWindow(); - -public slots: - - void hideByTimer(); - void checkLastInput(); - - void unlinkHistoryAndNotify(); - -private: - -#if defined Q_OS_WIN && !defined Q_OS_WINRT - DWORD started; -#endif // Q_OS_WIN && !Q_OS_WINRT - History *history; - HistoryItem *item; - int32 fwdCount; - IconedButton close; - QPixmap pm; - float64 alphaDuration, posDuration; - QTimer hideTimer, inputTimer; - bool hiding; - int32 _index; - anim::fvalue a_opacity; - anim::transition a_func; - anim::ivalue a_y; - Animation _a_appearance; - - ImagePtr peerPhoto; - -}; - -typedef QList NotifyWindows; - class MediaPreviewWidget; class MainWindow : public Platform::MainWindow, private base::Subscriber { @@ -204,12 +141,7 @@ public: void notifySchedule(History *history, HistoryItem *item); void notifyClear(History *history = 0); void notifyClearFast(); - void notifyShowNext(NotifyWindow *remove = 0); - void notifyItemRemoved(HistoryItem *item); - void notifyStopHiding(); - void notifyStartHiding(); void notifyUpdateAll(); - void notifyActivateAll(); QImage iconLarge() const; @@ -266,7 +198,7 @@ public slots: void onClearFinished(int task, void *manager); void onClearFailed(int task, void *manager); - void notifyFire(); + void notifyShowNext(); void updateTrayMenu(bool force = false); void onShowAddContact(); @@ -278,8 +210,6 @@ public slots: void onReActivate(); - void notifyUpdateAllPhotos(); - void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button); signals: @@ -333,28 +263,30 @@ private: SingleTimer _autoLockTimer; uint64 _shouldLockAt = 0; - typedef QMap NotifyWhenMap; - typedef QMap NotifyWhenMaps; - NotifyWhenMaps notifyWhenMaps; + using NotifyWhenMap = QMap; + using NotifyWhenMaps = QMap; + NotifyWhenMaps _notifyWhenMaps; struct NotifyWaiter { - NotifyWaiter(MsgId msg, uint64 when, PeerData *notifyByFrom) : msg(msg), when(when), notifyByFrom(notifyByFrom) { + NotifyWaiter(MsgId msg, uint64 when, PeerData *notifyByFrom) + : msg(msg) + , when(when) + , notifyByFrom(notifyByFrom) { } MsgId msg; uint64 when; PeerData *notifyByFrom; }; - typedef QMap NotifyWaiters; - NotifyWaiters notifyWaiters; - NotifyWaiters notifySettingWaiters; - SingleTimer notifyWaitTimer; + using NotifyWaiters = QMap; + NotifyWaiters _notifyWaiters; + NotifyWaiters _notifySettingWaiters; + SingleTimer _notifyWaitTimer; - typedef QMap NotifyWhenAlert; - typedef QMap NotifyWhenAlerts; - NotifyWhenAlerts notifyWhenAlerts; - - NotifyWindows notifyWindows; + using NotifyWhenAlert = QMap; + using NotifyWhenAlerts = QMap; + NotifyWhenAlerts _notifyWhenAlerts; MediaView *_mediaView = nullptr; + }; class PreLaunchWindow : public TWidget { diff --git a/Telegram/SourceFiles/media/media_audio.cpp b/Telegram/SourceFiles/media/media_audio.cpp index f1e3551f57..bed02e902f 100644 --- a/Telegram/SourceFiles/media/media_audio.cpp +++ b/Telegram/SourceFiles/media/media_audio.cpp @@ -985,13 +985,13 @@ void AudioPlayerFader::onTimer() { } else if (ms > _suppressAllStart + notifyLengthMs - AudioFadeDuration) { if (_suppressAllGain.to() != 1.) _suppressAllGain.start(1.); _suppressAllGain.update(1. - ((_suppressAllStart + notifyLengthMs - ms) / float64(AudioFadeDuration)), anim::linear); - } else if (ms >= _suppressAllStart + st::notifyFastAnim) { + } else if (ms >= _suppressAllStart + st::mediaPlayerSuppressDuration) { if (_suppressAllAnim) { _suppressAllGain.finish(); _suppressAllAnim = false; } } else if (ms > _suppressAllStart) { - _suppressAllGain.update((ms - _suppressAllStart) / st::notifyFastAnim, anim::linear); + _suppressAllGain.update((ms - _suppressAllStart) / st::mediaPlayerSuppressDuration, anim::linear); } suppressAllGain = _suppressAllGain.current(); suppressAudioChanged = (suppressAllGain != wasAudio); diff --git a/Telegram/SourceFiles/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp index 491eb8cdaf..fed6ed7c68 100644 --- a/Telegram/SourceFiles/media/media_audio_loaders.cpp +++ b/Telegram/SourceFiles/media/media_audio_loaders.cpp @@ -75,7 +75,7 @@ AudioPlayerLoaders::~AudioPlayerLoaders() { } void AudioPlayerLoaders::clearFromVideoQueue() { - auto queue = createAndSwap(_fromVideoQueue); + auto queue = base::take(_fromVideoQueue); for (auto &packetData : queue) { AVPacket packet; FFMpeg::packetFromDataWrap(packet, packetData); diff --git a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp index b5b7e8194f..20b645721f 100644 --- a/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp +++ b/Telegram/SourceFiles/media/media_child_ffmpeg_loader.cpp @@ -197,7 +197,7 @@ void ChildFFMpegLoader::enqueuePackets(QQueue &packets } ChildFFMpegLoader::~ChildFFMpegLoader() { - auto queue = createAndSwap(_queue); + auto queue = base::take(_queue); for (auto &packetData : queue) { AVPacket packet; FFMpeg::packetFromDataWrap(packet, packetData); diff --git a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp index aef676db3d..bd3abc4e07 100644 --- a/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp +++ b/Telegram/SourceFiles/media/media_clip_ffmpeg.cpp @@ -525,7 +525,7 @@ void FFMpegReaderImplementation::finishPacket() { void FFMpegReaderImplementation::clearPacketQueue() { finishPacket(); - auto packets = createAndSwap(_packetQueue); + auto packets = base::take(_packetQueue); for (auto &packetData : packets) { AVPacket packet; FFMpeg::packetFromDataWrap(packet, packetData); diff --git a/Telegram/SourceFiles/media/media_clip_qtgif.cpp b/Telegram/SourceFiles/media/media_clip_qtgif.cpp index 6ab82b1e26..e826246918 100644 --- a/Telegram/SourceFiles/media/media_clip_qtgif.cpp +++ b/Telegram/SourceFiles/media/media_clip_qtgif.cpp @@ -106,7 +106,7 @@ bool QtGifReaderImplementation::start(Mode mode, int64 &positionMs) { } QtGifReaderImplementation::~QtGifReaderImplementation() { - deleteAndMark(_reader); + delete base::take(_reader); } bool QtGifReaderImplementation::jumpToStart() { diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index d6be8535e2..3dbea71ac4 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -44,8 +44,7 @@ bool exists() { } void finish() { - auto temp = createAndSwap(SingleInstance); - delete temp; + delete base::take(SingleInstance); audioFinish(); } diff --git a/Telegram/SourceFiles/media/player/media_player_widget.h b/Telegram/SourceFiles/media/player/media_player_widget.h index fa63bd41b8..28d09e6175 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.h +++ b/Telegram/SourceFiles/media/player/media_player_widget.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" class ScrollArea; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 2bbd3b4620..fb0b9b98ca 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwindow.h" #include "application.h" #include "ui/filedialog.h" +#include "ui/popupmenu.h" #include "media/media_clip_reader.h" #include "media/view/media_clip_controller.h" #include "styles/style_mediaview.h" @@ -96,6 +97,12 @@ MediaView::MediaView() : TWidget(App::wnd()) connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(onScreenResized(int))); + subscribe(FileDownload::ImageLoaded(), [this] { + if (!isHidden()) { + updateControls(); + } + }); + _transparentBrush = QBrush(App::sprite().copy(st::mvTransparentBrush.rect())); setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::Tool | Qt::NoDropShadowWindowHint); @@ -612,7 +619,7 @@ void MediaView::clearData() { } MediaView::~MediaView() { - deleteAndMark(_menu); + delete base::take(_menu); } void MediaView::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 01c0bb2be4..3957b3ef80 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -29,9 +29,11 @@ class Controller; } // namespace Clip } // namespace Media +class PopupMenu; + struct AudioPlaybackState; -class MediaView : public TWidget, public RPCSender, public ClickHandlerHost { +class MediaView : public TWidget, private base::Subscriber, public RPCSender, public ClickHandlerHost { Q_OBJECT public: diff --git a/Telegram/SourceFiles/mtproto/auth_key.h b/Telegram/SourceFiles/mtproto/auth_key.h index 935eee4236..40dd3c6fb8 100644 --- a/Telegram/SourceFiles/mtproto/auth_key.h +++ b/Telegram/SourceFiles/mtproto/auth_key.h @@ -44,17 +44,17 @@ public: } uint32 getDC() const { - if (!_isset) throw mtpErrorKeyNotReady("getDC()"); + t_assert(_isset); return _dc; } uint64 keyId() const { - if (!_isset) throw mtpErrorKeyNotReady("keyId()"); + t_assert(_isset); return _keyId; } void prepareAES(const MTPint128 &msgKey, MTPint256 &aesKey, MTPint256 &aesIV, bool send = true) const { - if (!_isset) throw mtpErrorKeyNotReady(QString("prepareAES(..., %1)").arg(Logs::b(send))); + t_assert(_isset); uint32 x = send ? 0 : 8; @@ -90,7 +90,7 @@ public: } void write(QDataStream &to) const { - if (!_isset) throw mtpErrorKeyNotReady("write(...)"); + t_assert(_isset); to.writeRawData(_key, 256); } diff --git a/Telegram/SourceFiles/mtproto/connection.h b/Telegram/SourceFiles/mtproto/connection.h index 89c62fb4bf..ab21010858 100644 --- a/Telegram/SourceFiles/mtproto/connection.h +++ b/Telegram/SourceFiles/mtproto/connection.h @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mtproto/core_types.h" #include "mtproto/auth_key.h" #include "mtproto/connection_abstract.h" +#include "core/single_timer.h" namespace MTP { namespace internal { diff --git a/Telegram/SourceFiles/mtproto/connection_tcp.cpp b/Telegram/SourceFiles/mtproto/connection_tcp.cpp index 9e64751a43..4d73feab1a 100644 --- a/Telegram/SourceFiles/mtproto/connection_tcp.cpp +++ b/Telegram/SourceFiles/mtproto/connection_tcp.cpp @@ -298,7 +298,7 @@ void AbstractTCPConnection::tcpSend(mtpBuffer &buffer) { // prepare decryption key/iv char reversed[48]; memcpy(reversed, nonce + 8, sizeof(reversed)); - std::reverse(reversed, reversed + arraysize(reversed)); + std::reverse(reversed, reversed + base::array_size(reversed)); memcpy(_receiveKey, reversed, CTRState::KeySize); memcpy(_receiveState.ivec, reversed + CTRState::KeySize, CTRState::IvecSize); diff --git a/Telegram/SourceFiles/mtproto/core_types.h b/Telegram/SourceFiles/mtproto/core_types.h index e48a952be9..f716ed2301 100644 --- a/Telegram/SourceFiles/mtproto/core_types.h +++ b/Telegram/SourceFiles/mtproto/core_types.h @@ -199,30 +199,12 @@ public: } }; -class mtpErrorUninitialized : public Exception { -public: - mtpErrorUninitialized() : Exception("MTP Uninitialized variable write attempt") { - } -}; - class mtpErrorBadTypeId : public Exception { public: mtpErrorBadTypeId(mtpTypeId typeId, const QString &type) : Exception(QString("MTP Bad type id %1 passed to constructor of %2").arg(typeId).arg(type)) { } }; -class mtpErrorWrongTypeId : public Exception { -public: - mtpErrorWrongTypeId(mtpTypeId typeId, mtpTypeId required) : Exception(QString("MTP Wrong type id %1 for this data conversion, must be %2").arg(typeId).arg(required)) { - } -}; - -class mtpErrorKeyNotReady : public Exception { -public: - mtpErrorKeyNotReady(const QString &method) : Exception(QString("MTP Auth key is used in %1 without being created").arg(method)) { - } -}; - class mtpData { public: mtpData() : cnt(1) { @@ -686,12 +668,12 @@ public: } MTPDstring &_string() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDstring*)data; } const MTPDstring &c_string() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDstring*)data; } @@ -823,12 +805,12 @@ public: } MTPDvector &_vector() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDvector*)data; } const MTPDvector &c_vector() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDvector*)data; } diff --git a/Telegram/SourceFiles/mtproto/dcenter.h b/Telegram/SourceFiles/mtproto/dcenter.h index 4f47c63d33..058ab61fdb 100644 --- a/Telegram/SourceFiles/mtproto/dcenter.h +++ b/Telegram/SourceFiles/mtproto/dcenter.h @@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "core/single_timer.h" + namespace MTP { namespace internal { @@ -27,7 +29,6 @@ class Dcenter : public QObject { Q_OBJECT public: - Dcenter(int32 id, const AuthKeyPtr &key); QReadWriteLock *keyMutex() const; @@ -46,21 +47,19 @@ public: } signals: - void authKeyCreated(); void layerWasInited(bool was); private slots: - void authKeyWrite(); private: - mutable QReadWriteLock keyLock; mutable QMutex initLock; int32 _id; AuthKeyPtr _key; bool _connectionInited; + }; typedef QSharedPointer DcenterPtr; @@ -70,21 +69,17 @@ class ConfigLoader : public QObject { Q_OBJECT public: - ConfigLoader(); void load(); void done(); public slots: - void enumDC(); signals: - void loaded(); private: - SingleTimer _enumDCTimer; int32 _enumCurrent; mtpRequestId _enumRequest; diff --git a/Telegram/SourceFiles/mtproto/facade.h b/Telegram/SourceFiles/mtproto/facade.h index 85aa9c6866..dacb58e177 100644 --- a/Telegram/SourceFiles/mtproto/facade.h +++ b/Telegram/SourceFiles/mtproto/facade.h @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mtproto/core_types.h" #include "mtproto/session.h" +#include "core/single_timer.h" namespace MTP { @@ -57,17 +58,15 @@ class GlobalSlotCarrier : public QObject { Q_OBJECT public: - GlobalSlotCarrier(); public slots: - void checkDelayed(); void connectionFinished(Connection *connection); private: - SingleTimer _timer; + }; GlobalSlotCarrier *globalSlotCarrier(); diff --git a/Telegram/SourceFiles/mtproto/generate.py b/Telegram/SourceFiles/mtproto/generate.py index e55643944c..fabe2d5ca9 100644 --- a/Telegram/SourceFiles/mtproto/generate.py +++ b/Telegram/SourceFiles/mtproto/generate.py @@ -612,17 +612,19 @@ for restype in typesList: withData = 1; getters += '\n\tMTPD' + name + ' &_' + name + '() {\n'; # splitting getter - getters += '\t\tif (!data) throw mtpErrorUninitialized();\n'; if (withType): - getters += '\t\tif (_type != mtpc_' + name + ') throw mtpErrorWrongTypeId(_type, mtpc_' + name + ');\n'; + getters += '\t\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n'; + else: + getters += '\t\tt_assert(data != nullptr);\n'; getters += '\t\tsplit();\n'; getters += '\t\treturn *(MTPD' + name + '*)data;\n'; getters += '\t}\n'; getters += '\tconst MTPD' + name + ' &c_' + name + '() const {\n'; # const getter - getters += '\t\tif (!data) throw mtpErrorUninitialized();\n'; if (withType): - getters += '\t\tif (_type != mtpc_' + name + ') throw mtpErrorWrongTypeId(_type, mtpc_' + name + ');\n'; + getters += '\t\tt_assert(data != nullptr && _type == mtpc_' + name + ');\n'; + else: + getters += '\t\tt_assert(data != nullptr);\n'; getters += '\t\treturn *(const MTPD' + name + '*)data;\n'; getters += '\t}\n'; @@ -783,7 +785,7 @@ for restype in typesList: typesText += '\tmtpTypeId type() const;\n'; # type id method inlineMethods += 'inline mtpTypeId MTP' + restype + '::type() const {\n'; if (withType): - inlineMethods += '\tif (!_type) throw mtpErrorUninitialized();\n'; + inlineMethods += '\tt_assert(_type != 0);\n'; inlineMethods += '\treturn _type;\n'; else: inlineMethods += '\treturn mtpc_' + v[0][0] + ';\n'; diff --git a/Telegram/SourceFiles/mtproto/rpc_sender.h b/Telegram/SourceFiles/mtproto/rpc_sender.h index fb5fd95eb9..76839e5a17 100644 --- a/Telegram/SourceFiles/mtproto/rpc_sender.h +++ b/Telegram/SourceFiles/mtproto/rpc_sender.h @@ -20,9 +20,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "core/lambda_wrap.h" + class RPCError { public: - RPCError(const MTPrpcError &error) : _code(error.c_rpc_error().verror_code.v) { QString text = qs(error.c_rpc_error().verror_message); if (_code < 0 || _code >= 500) { @@ -827,3 +828,187 @@ protected: typedef void (*MTPStateChangedHandler)(int32 dcId, int32 state); typedef void(*MTPSessionResetHandler)(int32 dcId); + +template +struct LambdaUniqueHelper; + +template +struct LambdaUniqueHelper { + using UniqueType = base::lambda_unique; +}; + +template +using LambdaGetUnique = typename LambdaUniqueHelper::UniqueType; + +template +class RPCHandlerImplementation : public Base { +protected: + using Lambda = base::lambda_unique; + using Parent = RPCHandlerImplementation; + +public: + RPCHandlerImplementation(Lambda &&handler) : _handler(std_::move(handler)) { + } + +protected: + Lambda _handler; + +}; + +template +using RPCDoneHandlerImplementation = RPCHandlerImplementation; + +template +class RPCDoneHandlerImplementationBare : public RPCDoneHandlerImplementation { // done(from, end) +public: + using RPCDoneHandlerImplementation::Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(from, end) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationBareReq : public RPCDoneHandlerImplementation { // done(from, end, req_id) +public: + using RPCDoneHandlerImplementation::Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(from, end, requestId) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationPlain : public RPCDoneHandlerImplementation { // done(result) +public: + using RPCDoneHandlerImplementation::Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(T(from, end)) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationReq : public RPCDoneHandlerImplementation { // done(result, req_id) +public: + using RPCDoneHandlerImplementation::Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(T(from, end), requestId) : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationNo : public RPCDoneHandlerImplementation { // done() +public: + using RPCDoneHandlerImplementation::Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler() : void(0); + } + +}; + +template +class RPCDoneHandlerImplementationNoReq : public RPCDoneHandlerImplementation { // done(req_id) +public: + using RPCDoneHandlerImplementation::Parent::Parent; + void operator()(mtpRequestId requestId, const mtpPrime *from, const mtpPrime *end) const override { + return this->_handler ? this->_handler(requestId) : void(0); + } + +}; + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationBare(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationBareReq(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationPlain(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationReq(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationNo(std_::move(lambda))); +} + +template +inline RPCDoneHandlerPtr rpcDone_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCDoneHandlerPtr(new RPCDoneHandlerImplementationNoReq(std_::move(lambda))); +} + +template ::value>> +RPCDoneHandlerPtr rpcDone(Lambda &&lambda) { + return rpcDone_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); +} + +template +using RPCFailHandlerImplementation = RPCHandlerImplementation; + +class RPCFailHandlerImplementationPlain : public RPCFailHandlerImplementation { // fail(error) +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return _handler ? _handler(error) : true; + } + +}; + +class RPCFailHandlerImplementationReq : public RPCFailHandlerImplementation { // fail(error, req_id) +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return this->_handler ? this->_handler(error, requestId) : true; + } + +}; + +class RPCFailHandlerImplementationNo : public RPCFailHandlerImplementation { // fail() +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return this->_handler ? this->_handler() : true; + } + +}; + +class RPCFailHandlerImplementationNoReq : public RPCFailHandlerImplementation { // fail(req_id) +public: + using Parent::Parent; + bool operator()(mtpRequestId requestId, const RPCError &error) const override { + return this->_handler ? this->_handler(requestId) : true; + } + +}; + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationPlain(std_::move(lambda))); +} + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationReq(std_::move(lambda))); +} + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationNo(std_::move(lambda))); +} + +inline RPCFailHandlerPtr rpcFail_lambda_wrap_helper(base::lambda_unique &&lambda) { + return RPCFailHandlerPtr(new RPCFailHandlerImplementationNoReq(std_::move(lambda))); +} + +template ::value>> +RPCFailHandlerPtr rpcFail(Lambda &&lambda) { + return rpcFail_lambda_wrap_helper(LambdaGetUnique(std_::move(lambda))); +} diff --git a/Telegram/SourceFiles/mtproto/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h index d723604770..5926b39975 100644 --- a/Telegram/SourceFiles/mtproto/scheme_auto.h +++ b/Telegram/SourceFiles/mtproto/scheme_auto.h @@ -1633,12 +1633,12 @@ public: } MTPDresPQ &_resPQ() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDresPQ*)data; } const MTPDresPQ &c_resPQ() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDresPQ*)data; } @@ -1664,12 +1664,12 @@ public: } MTPDp_q_inner_data &_p_q_inner_data() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDp_q_inner_data*)data; } const MTPDp_q_inner_data &c_p_q_inner_data() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDp_q_inner_data*)data; } @@ -1696,26 +1696,22 @@ public: } MTPDserver_DH_params_fail &_server_DH_params_fail() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_server_DH_params_fail) throw mtpErrorWrongTypeId(_type, mtpc_server_DH_params_fail); + t_assert(data != nullptr && _type == mtpc_server_DH_params_fail); split(); return *(MTPDserver_DH_params_fail*)data; } const MTPDserver_DH_params_fail &c_server_DH_params_fail() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_server_DH_params_fail) throw mtpErrorWrongTypeId(_type, mtpc_server_DH_params_fail); + t_assert(data != nullptr && _type == mtpc_server_DH_params_fail); return *(const MTPDserver_DH_params_fail*)data; } MTPDserver_DH_params_ok &_server_DH_params_ok() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_server_DH_params_ok) throw mtpErrorWrongTypeId(_type, mtpc_server_DH_params_ok); + t_assert(data != nullptr && _type == mtpc_server_DH_params_ok); split(); return *(MTPDserver_DH_params_ok*)data; } const MTPDserver_DH_params_ok &c_server_DH_params_ok() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_server_DH_params_ok) throw mtpErrorWrongTypeId(_type, mtpc_server_DH_params_ok); + t_assert(data != nullptr && _type == mtpc_server_DH_params_ok); return *(const MTPDserver_DH_params_ok*)data; } @@ -1745,12 +1741,12 @@ public: } MTPDserver_DH_inner_data &_server_DH_inner_data() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDserver_DH_inner_data*)data; } const MTPDserver_DH_inner_data &c_server_DH_inner_data() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDserver_DH_inner_data*)data; } @@ -1776,12 +1772,12 @@ public: } MTPDclient_DH_inner_data &_client_DH_inner_data() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDclient_DH_inner_data*)data; } const MTPDclient_DH_inner_data &c_client_DH_inner_data() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDclient_DH_inner_data*)data; } @@ -1808,38 +1804,32 @@ public: } MTPDdh_gen_ok &_dh_gen_ok() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_dh_gen_ok) throw mtpErrorWrongTypeId(_type, mtpc_dh_gen_ok); + t_assert(data != nullptr && _type == mtpc_dh_gen_ok); split(); return *(MTPDdh_gen_ok*)data; } const MTPDdh_gen_ok &c_dh_gen_ok() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_dh_gen_ok) throw mtpErrorWrongTypeId(_type, mtpc_dh_gen_ok); + t_assert(data != nullptr && _type == mtpc_dh_gen_ok); return *(const MTPDdh_gen_ok*)data; } MTPDdh_gen_retry &_dh_gen_retry() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_dh_gen_retry) throw mtpErrorWrongTypeId(_type, mtpc_dh_gen_retry); + t_assert(data != nullptr && _type == mtpc_dh_gen_retry); split(); return *(MTPDdh_gen_retry*)data; } const MTPDdh_gen_retry &c_dh_gen_retry() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_dh_gen_retry) throw mtpErrorWrongTypeId(_type, mtpc_dh_gen_retry); + t_assert(data != nullptr && _type == mtpc_dh_gen_retry); return *(const MTPDdh_gen_retry*)data; } MTPDdh_gen_fail &_dh_gen_fail() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_dh_gen_fail) throw mtpErrorWrongTypeId(_type, mtpc_dh_gen_fail); + t_assert(data != nullptr && _type == mtpc_dh_gen_fail); split(); return *(MTPDdh_gen_fail*)data; } const MTPDdh_gen_fail &c_dh_gen_fail() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_dh_gen_fail) throw mtpErrorWrongTypeId(_type, mtpc_dh_gen_fail); + t_assert(data != nullptr && _type == mtpc_dh_gen_fail); return *(const MTPDdh_gen_fail*)data; } @@ -1870,12 +1860,12 @@ public: } MTPDmsgs_ack &_msgs_ack() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmsgs_ack*)data; } const MTPDmsgs_ack &c_msgs_ack() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmsgs_ack*)data; } @@ -1902,26 +1892,22 @@ public: } MTPDbad_msg_notification &_bad_msg_notification() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_bad_msg_notification) throw mtpErrorWrongTypeId(_type, mtpc_bad_msg_notification); + t_assert(data != nullptr && _type == mtpc_bad_msg_notification); split(); return *(MTPDbad_msg_notification*)data; } const MTPDbad_msg_notification &c_bad_msg_notification() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_bad_msg_notification) throw mtpErrorWrongTypeId(_type, mtpc_bad_msg_notification); + t_assert(data != nullptr && _type == mtpc_bad_msg_notification); return *(const MTPDbad_msg_notification*)data; } MTPDbad_server_salt &_bad_server_salt() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_bad_server_salt) throw mtpErrorWrongTypeId(_type, mtpc_bad_server_salt); + t_assert(data != nullptr && _type == mtpc_bad_server_salt); split(); return *(MTPDbad_server_salt*)data; } const MTPDbad_server_salt &c_bad_server_salt() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_bad_server_salt) throw mtpErrorWrongTypeId(_type, mtpc_bad_server_salt); + t_assert(data != nullptr && _type == mtpc_bad_server_salt); return *(const MTPDbad_server_salt*)data; } @@ -1951,12 +1937,12 @@ public: } MTPDmsgs_state_req &_msgs_state_req() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmsgs_state_req*)data; } const MTPDmsgs_state_req &c_msgs_state_req() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmsgs_state_req*)data; } @@ -1982,12 +1968,12 @@ public: } MTPDmsgs_state_info &_msgs_state_info() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmsgs_state_info*)data; } const MTPDmsgs_state_info &c_msgs_state_info() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmsgs_state_info*)data; } @@ -2013,12 +1999,12 @@ public: } MTPDmsgs_all_info &_msgs_all_info() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmsgs_all_info*)data; } const MTPDmsgs_all_info &c_msgs_all_info() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmsgs_all_info*)data; } @@ -2045,26 +2031,22 @@ public: } MTPDmsg_detailed_info &_msg_detailed_info() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_msg_detailed_info) throw mtpErrorWrongTypeId(_type, mtpc_msg_detailed_info); + t_assert(data != nullptr && _type == mtpc_msg_detailed_info); split(); return *(MTPDmsg_detailed_info*)data; } const MTPDmsg_detailed_info &c_msg_detailed_info() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_msg_detailed_info) throw mtpErrorWrongTypeId(_type, mtpc_msg_detailed_info); + t_assert(data != nullptr && _type == mtpc_msg_detailed_info); return *(const MTPDmsg_detailed_info*)data; } MTPDmsg_new_detailed_info &_msg_new_detailed_info() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_msg_new_detailed_info) throw mtpErrorWrongTypeId(_type, mtpc_msg_new_detailed_info); + t_assert(data != nullptr && _type == mtpc_msg_new_detailed_info); split(); return *(MTPDmsg_new_detailed_info*)data; } const MTPDmsg_new_detailed_info &c_msg_new_detailed_info() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_msg_new_detailed_info) throw mtpErrorWrongTypeId(_type, mtpc_msg_new_detailed_info); + t_assert(data != nullptr && _type == mtpc_msg_new_detailed_info); return *(const MTPDmsg_new_detailed_info*)data; } @@ -2094,12 +2076,12 @@ public: } MTPDmsg_resend_req &_msg_resend_req() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmsg_resend_req*)data; } const MTPDmsg_resend_req &c_msg_resend_req() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmsg_resend_req*)data; } @@ -2125,12 +2107,12 @@ public: } MTPDrpc_error &_rpc_error() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDrpc_error*)data; } const MTPDrpc_error &c_rpc_error() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDrpc_error*)data; } @@ -2157,14 +2139,12 @@ public: } MTPDrpc_answer_dropped &_rpc_answer_dropped() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_rpc_answer_dropped) throw mtpErrorWrongTypeId(_type, mtpc_rpc_answer_dropped); + t_assert(data != nullptr && _type == mtpc_rpc_answer_dropped); split(); return *(MTPDrpc_answer_dropped*)data; } const MTPDrpc_answer_dropped &c_rpc_answer_dropped() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_rpc_answer_dropped) throw mtpErrorWrongTypeId(_type, mtpc_rpc_answer_dropped); + t_assert(data != nullptr && _type == mtpc_rpc_answer_dropped); return *(const MTPDrpc_answer_dropped*)data; } @@ -2193,12 +2173,12 @@ public: } MTPDfuture_salt &_future_salt() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDfuture_salt*)data; } const MTPDfuture_salt &c_future_salt() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDfuture_salt*)data; } @@ -2224,12 +2204,12 @@ public: } MTPDfuture_salts &_future_salts() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDfuture_salts*)data; } const MTPDfuture_salts &c_future_salts() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDfuture_salts*)data; } @@ -2255,12 +2235,12 @@ public: } MTPDpong &_pong() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDpong*)data; } const MTPDpong &c_pong() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDpong*)data; } @@ -2287,26 +2267,22 @@ public: } MTPDdestroy_session_ok &_destroy_session_ok() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_destroy_session_ok) throw mtpErrorWrongTypeId(_type, mtpc_destroy_session_ok); + t_assert(data != nullptr && _type == mtpc_destroy_session_ok); split(); return *(MTPDdestroy_session_ok*)data; } const MTPDdestroy_session_ok &c_destroy_session_ok() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_destroy_session_ok) throw mtpErrorWrongTypeId(_type, mtpc_destroy_session_ok); + t_assert(data != nullptr && _type == mtpc_destroy_session_ok); return *(const MTPDdestroy_session_ok*)data; } MTPDdestroy_session_none &_destroy_session_none() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_destroy_session_none) throw mtpErrorWrongTypeId(_type, mtpc_destroy_session_none); + t_assert(data != nullptr && _type == mtpc_destroy_session_none); split(); return *(MTPDdestroy_session_none*)data; } const MTPDdestroy_session_none &c_destroy_session_none() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_destroy_session_none) throw mtpErrorWrongTypeId(_type, mtpc_destroy_session_none); + t_assert(data != nullptr && _type == mtpc_destroy_session_none); return *(const MTPDdestroy_session_none*)data; } @@ -2336,12 +2312,12 @@ public: } MTPDnew_session_created &_new_session_created() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDnew_session_created*)data; } const MTPDnew_session_created &c_new_session_created() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDnew_session_created*)data; } @@ -2367,12 +2343,12 @@ public: } MTPDhttp_wait &_http_wait() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDhttp_wait*)data; } const MTPDhttp_wait &c_http_wait() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDhttp_wait*)data; } @@ -2443,12 +2419,12 @@ public: } MTPDerror &_error() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDerror*)data; } const MTPDerror &c_error() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDerror*)data; } @@ -2496,38 +2472,32 @@ public: } MTPDinputPeerChat &_inputPeerChat() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPeerChat) throw mtpErrorWrongTypeId(_type, mtpc_inputPeerChat); + t_assert(data != nullptr && _type == mtpc_inputPeerChat); split(); return *(MTPDinputPeerChat*)data; } const MTPDinputPeerChat &c_inputPeerChat() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPeerChat) throw mtpErrorWrongTypeId(_type, mtpc_inputPeerChat); + t_assert(data != nullptr && _type == mtpc_inputPeerChat); return *(const MTPDinputPeerChat*)data; } MTPDinputPeerUser &_inputPeerUser() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPeerUser) throw mtpErrorWrongTypeId(_type, mtpc_inputPeerUser); + t_assert(data != nullptr && _type == mtpc_inputPeerUser); split(); return *(MTPDinputPeerUser*)data; } const MTPDinputPeerUser &c_inputPeerUser() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPeerUser) throw mtpErrorWrongTypeId(_type, mtpc_inputPeerUser); + t_assert(data != nullptr && _type == mtpc_inputPeerUser); return *(const MTPDinputPeerUser*)data; } MTPDinputPeerChannel &_inputPeerChannel() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPeerChannel) throw mtpErrorWrongTypeId(_type, mtpc_inputPeerChannel); + t_assert(data != nullptr && _type == mtpc_inputPeerChannel); split(); return *(MTPDinputPeerChannel*)data; } const MTPDinputPeerChannel &c_inputPeerChannel() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPeerChannel) throw mtpErrorWrongTypeId(_type, mtpc_inputPeerChannel); + t_assert(data != nullptr && _type == mtpc_inputPeerChannel); return *(const MTPDinputPeerChannel*)data; } @@ -2559,14 +2529,12 @@ public: } MTPDinputUser &_inputUser() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputUser) throw mtpErrorWrongTypeId(_type, mtpc_inputUser); + t_assert(data != nullptr && _type == mtpc_inputUser); split(); return *(MTPDinputUser*)data; } const MTPDinputUser &c_inputUser() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputUser) throw mtpErrorWrongTypeId(_type, mtpc_inputUser); + t_assert(data != nullptr && _type == mtpc_inputUser); return *(const MTPDinputUser*)data; } @@ -2595,12 +2563,12 @@ public: } MTPDinputPhoneContact &_inputPhoneContact() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDinputPhoneContact*)data; } const MTPDinputPhoneContact &c_inputPhoneContact() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDinputPhoneContact*)data; } @@ -2627,26 +2595,22 @@ public: } MTPDinputFile &_inputFile() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputFile) throw mtpErrorWrongTypeId(_type, mtpc_inputFile); + t_assert(data != nullptr && _type == mtpc_inputFile); split(); return *(MTPDinputFile*)data; } const MTPDinputFile &c_inputFile() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputFile) throw mtpErrorWrongTypeId(_type, mtpc_inputFile); + t_assert(data != nullptr && _type == mtpc_inputFile); return *(const MTPDinputFile*)data; } MTPDinputFileBig &_inputFileBig() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputFileBig) throw mtpErrorWrongTypeId(_type, mtpc_inputFileBig); + t_assert(data != nullptr && _type == mtpc_inputFileBig); split(); return *(MTPDinputFileBig*)data; } const MTPDinputFileBig &c_inputFileBig() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputFileBig) throw mtpErrorWrongTypeId(_type, mtpc_inputFileBig); + t_assert(data != nullptr && _type == mtpc_inputFileBig); return *(const MTPDinputFileBig*)data; } @@ -2677,146 +2641,122 @@ public: } MTPDinputMediaUploadedPhoto &_inputMediaUploadedPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaUploadedPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedPhoto); + t_assert(data != nullptr && _type == mtpc_inputMediaUploadedPhoto); split(); return *(MTPDinputMediaUploadedPhoto*)data; } const MTPDinputMediaUploadedPhoto &c_inputMediaUploadedPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaUploadedPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedPhoto); + t_assert(data != nullptr && _type == mtpc_inputMediaUploadedPhoto); return *(const MTPDinputMediaUploadedPhoto*)data; } MTPDinputMediaPhoto &_inputMediaPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaPhoto); + t_assert(data != nullptr && _type == mtpc_inputMediaPhoto); split(); return *(MTPDinputMediaPhoto*)data; } const MTPDinputMediaPhoto &c_inputMediaPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaPhoto); + t_assert(data != nullptr && _type == mtpc_inputMediaPhoto); return *(const MTPDinputMediaPhoto*)data; } MTPDinputMediaGeoPoint &_inputMediaGeoPoint() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaGeoPoint) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaGeoPoint); + t_assert(data != nullptr && _type == mtpc_inputMediaGeoPoint); split(); return *(MTPDinputMediaGeoPoint*)data; } const MTPDinputMediaGeoPoint &c_inputMediaGeoPoint() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaGeoPoint) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaGeoPoint); + t_assert(data != nullptr && _type == mtpc_inputMediaGeoPoint); return *(const MTPDinputMediaGeoPoint*)data; } MTPDinputMediaContact &_inputMediaContact() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaContact); + t_assert(data != nullptr && _type == mtpc_inputMediaContact); split(); return *(MTPDinputMediaContact*)data; } const MTPDinputMediaContact &c_inputMediaContact() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaContact); + t_assert(data != nullptr && _type == mtpc_inputMediaContact); return *(const MTPDinputMediaContact*)data; } MTPDinputMediaUploadedDocument &_inputMediaUploadedDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaUploadedDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedDocument); + t_assert(data != nullptr && _type == mtpc_inputMediaUploadedDocument); split(); return *(MTPDinputMediaUploadedDocument*)data; } const MTPDinputMediaUploadedDocument &c_inputMediaUploadedDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaUploadedDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedDocument); + t_assert(data != nullptr && _type == mtpc_inputMediaUploadedDocument); return *(const MTPDinputMediaUploadedDocument*)data; } MTPDinputMediaUploadedThumbDocument &_inputMediaUploadedThumbDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaUploadedThumbDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedThumbDocument); + t_assert(data != nullptr && _type == mtpc_inputMediaUploadedThumbDocument); split(); return *(MTPDinputMediaUploadedThumbDocument*)data; } const MTPDinputMediaUploadedThumbDocument &c_inputMediaUploadedThumbDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaUploadedThumbDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaUploadedThumbDocument); + t_assert(data != nullptr && _type == mtpc_inputMediaUploadedThumbDocument); return *(const MTPDinputMediaUploadedThumbDocument*)data; } MTPDinputMediaDocument &_inputMediaDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaDocument); + t_assert(data != nullptr && _type == mtpc_inputMediaDocument); split(); return *(MTPDinputMediaDocument*)data; } const MTPDinputMediaDocument &c_inputMediaDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaDocument); + t_assert(data != nullptr && _type == mtpc_inputMediaDocument); return *(const MTPDinputMediaDocument*)data; } MTPDinputMediaVenue &_inputMediaVenue() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaVenue); + t_assert(data != nullptr && _type == mtpc_inputMediaVenue); split(); return *(MTPDinputMediaVenue*)data; } const MTPDinputMediaVenue &c_inputMediaVenue() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaVenue); + t_assert(data != nullptr && _type == mtpc_inputMediaVenue); return *(const MTPDinputMediaVenue*)data; } MTPDinputMediaGifExternal &_inputMediaGifExternal() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaGifExternal) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaGifExternal); + t_assert(data != nullptr && _type == mtpc_inputMediaGifExternal); split(); return *(MTPDinputMediaGifExternal*)data; } const MTPDinputMediaGifExternal &c_inputMediaGifExternal() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaGifExternal) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaGifExternal); + t_assert(data != nullptr && _type == mtpc_inputMediaGifExternal); return *(const MTPDinputMediaGifExternal*)data; } MTPDinputMediaPhotoExternal &_inputMediaPhotoExternal() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaPhotoExternal) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaPhotoExternal); + t_assert(data != nullptr && _type == mtpc_inputMediaPhotoExternal); split(); return *(MTPDinputMediaPhotoExternal*)data; } const MTPDinputMediaPhotoExternal &c_inputMediaPhotoExternal() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaPhotoExternal) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaPhotoExternal); + t_assert(data != nullptr && _type == mtpc_inputMediaPhotoExternal); return *(const MTPDinputMediaPhotoExternal*)data; } MTPDinputMediaDocumentExternal &_inputMediaDocumentExternal() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaDocumentExternal) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaDocumentExternal); + t_assert(data != nullptr && _type == mtpc_inputMediaDocumentExternal); split(); return *(MTPDinputMediaDocumentExternal*)data; } const MTPDinputMediaDocumentExternal &c_inputMediaDocumentExternal() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaDocumentExternal) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaDocumentExternal); + t_assert(data != nullptr && _type == mtpc_inputMediaDocumentExternal); return *(const MTPDinputMediaDocumentExternal*)data; } MTPDinputMediaGame &_inputMediaGame() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaGame) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaGame); + t_assert(data != nullptr && _type == mtpc_inputMediaGame); split(); return *(MTPDinputMediaGame*)data; } const MTPDinputMediaGame &c_inputMediaGame() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMediaGame) throw mtpErrorWrongTypeId(_type, mtpc_inputMediaGame); + t_assert(data != nullptr && _type == mtpc_inputMediaGame); return *(const MTPDinputMediaGame*)data; } @@ -2857,26 +2797,22 @@ public: } MTPDinputChatUploadedPhoto &_inputChatUploadedPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputChatUploadedPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputChatUploadedPhoto); + t_assert(data != nullptr && _type == mtpc_inputChatUploadedPhoto); split(); return *(MTPDinputChatUploadedPhoto*)data; } const MTPDinputChatUploadedPhoto &c_inputChatUploadedPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputChatUploadedPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputChatUploadedPhoto); + t_assert(data != nullptr && _type == mtpc_inputChatUploadedPhoto); return *(const MTPDinputChatUploadedPhoto*)data; } MTPDinputChatPhoto &_inputChatPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputChatPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputChatPhoto); + t_assert(data != nullptr && _type == mtpc_inputChatPhoto); split(); return *(MTPDinputChatPhoto*)data; } const MTPDinputChatPhoto &c_inputChatPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputChatPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputChatPhoto); + t_assert(data != nullptr && _type == mtpc_inputChatPhoto); return *(const MTPDinputChatPhoto*)data; } @@ -2907,14 +2843,12 @@ public: } MTPDinputGeoPoint &_inputGeoPoint() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputGeoPoint) throw mtpErrorWrongTypeId(_type, mtpc_inputGeoPoint); + t_assert(data != nullptr && _type == mtpc_inputGeoPoint); split(); return *(MTPDinputGeoPoint*)data; } const MTPDinputGeoPoint &c_inputGeoPoint() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputGeoPoint) throw mtpErrorWrongTypeId(_type, mtpc_inputGeoPoint); + t_assert(data != nullptr && _type == mtpc_inputGeoPoint); return *(const MTPDinputGeoPoint*)data; } @@ -2944,14 +2878,12 @@ public: } MTPDinputPhoto &_inputPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputPhoto); + t_assert(data != nullptr && _type == mtpc_inputPhoto); split(); return *(MTPDinputPhoto*)data; } const MTPDinputPhoto &c_inputPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputPhoto); + t_assert(data != nullptr && _type == mtpc_inputPhoto); return *(const MTPDinputPhoto*)data; } @@ -2981,38 +2913,32 @@ public: } MTPDinputFileLocation &_inputFileLocation() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputFileLocation); + t_assert(data != nullptr && _type == mtpc_inputFileLocation); split(); return *(MTPDinputFileLocation*)data; } const MTPDinputFileLocation &c_inputFileLocation() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputFileLocation); + t_assert(data != nullptr && _type == mtpc_inputFileLocation); return *(const MTPDinputFileLocation*)data; } MTPDinputEncryptedFileLocation &_inputEncryptedFileLocation() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileLocation); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFileLocation); split(); return *(MTPDinputEncryptedFileLocation*)data; } const MTPDinputEncryptedFileLocation &c_inputEncryptedFileLocation() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileLocation); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFileLocation); return *(const MTPDinputEncryptedFileLocation*)data; } MTPDinputDocumentFileLocation &_inputDocumentFileLocation() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputDocumentFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputDocumentFileLocation); + t_assert(data != nullptr && _type == mtpc_inputDocumentFileLocation); split(); return *(MTPDinputDocumentFileLocation*)data; } const MTPDinputDocumentFileLocation &c_inputDocumentFileLocation() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputDocumentFileLocation) throw mtpErrorWrongTypeId(_type, mtpc_inputDocumentFileLocation); + t_assert(data != nullptr && _type == mtpc_inputDocumentFileLocation); return *(const MTPDinputDocumentFileLocation*)data; } @@ -3043,12 +2969,12 @@ public: } MTPDinputAppEvent &_inputAppEvent() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDinputAppEvent*)data; } const MTPDinputAppEvent &c_inputAppEvent() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDinputAppEvent*)data; } @@ -3075,38 +3001,32 @@ public: } MTPDpeerUser &_peerUser() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerUser) throw mtpErrorWrongTypeId(_type, mtpc_peerUser); + t_assert(data != nullptr && _type == mtpc_peerUser); split(); return *(MTPDpeerUser*)data; } const MTPDpeerUser &c_peerUser() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerUser) throw mtpErrorWrongTypeId(_type, mtpc_peerUser); + t_assert(data != nullptr && _type == mtpc_peerUser); return *(const MTPDpeerUser*)data; } MTPDpeerChat &_peerChat() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerChat) throw mtpErrorWrongTypeId(_type, mtpc_peerChat); + t_assert(data != nullptr && _type == mtpc_peerChat); split(); return *(MTPDpeerChat*)data; } const MTPDpeerChat &c_peerChat() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerChat) throw mtpErrorWrongTypeId(_type, mtpc_peerChat); + t_assert(data != nullptr && _type == mtpc_peerChat); return *(const MTPDpeerChat*)data; } MTPDpeerChannel &_peerChannel() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerChannel) throw mtpErrorWrongTypeId(_type, mtpc_peerChannel); + t_assert(data != nullptr && _type == mtpc_peerChannel); split(); return *(MTPDpeerChannel*)data; } const MTPDpeerChannel &c_peerChannel() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerChannel) throw mtpErrorWrongTypeId(_type, mtpc_peerChannel); + t_assert(data != nullptr && _type == mtpc_peerChannel); return *(const MTPDpeerChannel*)data; } @@ -3162,26 +3082,22 @@ public: } MTPDfileLocationUnavailable &_fileLocationUnavailable() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_fileLocationUnavailable) throw mtpErrorWrongTypeId(_type, mtpc_fileLocationUnavailable); + t_assert(data != nullptr && _type == mtpc_fileLocationUnavailable); split(); return *(MTPDfileLocationUnavailable*)data; } const MTPDfileLocationUnavailable &c_fileLocationUnavailable() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_fileLocationUnavailable) throw mtpErrorWrongTypeId(_type, mtpc_fileLocationUnavailable); + t_assert(data != nullptr && _type == mtpc_fileLocationUnavailable); return *(const MTPDfileLocationUnavailable*)data; } MTPDfileLocation &_fileLocation() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_fileLocation) throw mtpErrorWrongTypeId(_type, mtpc_fileLocation); + t_assert(data != nullptr && _type == mtpc_fileLocation); split(); return *(MTPDfileLocation*)data; } const MTPDfileLocation &c_fileLocation() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_fileLocation) throw mtpErrorWrongTypeId(_type, mtpc_fileLocation); + t_assert(data != nullptr && _type == mtpc_fileLocation); return *(const MTPDfileLocation*)data; } @@ -3212,26 +3128,22 @@ public: } MTPDuserEmpty &_userEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userEmpty) throw mtpErrorWrongTypeId(_type, mtpc_userEmpty); + t_assert(data != nullptr && _type == mtpc_userEmpty); split(); return *(MTPDuserEmpty*)data; } const MTPDuserEmpty &c_userEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userEmpty) throw mtpErrorWrongTypeId(_type, mtpc_userEmpty); + t_assert(data != nullptr && _type == mtpc_userEmpty); return *(const MTPDuserEmpty*)data; } MTPDuser &_user() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_user) throw mtpErrorWrongTypeId(_type, mtpc_user); + t_assert(data != nullptr && _type == mtpc_user); split(); return *(MTPDuser*)data; } const MTPDuser &c_user() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_user) throw mtpErrorWrongTypeId(_type, mtpc_user); + t_assert(data != nullptr && _type == mtpc_user); return *(const MTPDuser*)data; } @@ -3262,14 +3174,12 @@ public: } MTPDuserProfilePhoto &_userProfilePhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userProfilePhoto) throw mtpErrorWrongTypeId(_type, mtpc_userProfilePhoto); + t_assert(data != nullptr && _type == mtpc_userProfilePhoto); split(); return *(MTPDuserProfilePhoto*)data; } const MTPDuserProfilePhoto &c_userProfilePhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userProfilePhoto) throw mtpErrorWrongTypeId(_type, mtpc_userProfilePhoto); + t_assert(data != nullptr && _type == mtpc_userProfilePhoto); return *(const MTPDuserProfilePhoto*)data; } @@ -3299,26 +3209,22 @@ public: } MTPDuserStatusOnline &_userStatusOnline() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userStatusOnline) throw mtpErrorWrongTypeId(_type, mtpc_userStatusOnline); + t_assert(data != nullptr && _type == mtpc_userStatusOnline); split(); return *(MTPDuserStatusOnline*)data; } const MTPDuserStatusOnline &c_userStatusOnline() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userStatusOnline) throw mtpErrorWrongTypeId(_type, mtpc_userStatusOnline); + t_assert(data != nullptr && _type == mtpc_userStatusOnline); return *(const MTPDuserStatusOnline*)data; } MTPDuserStatusOffline &_userStatusOffline() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userStatusOffline) throw mtpErrorWrongTypeId(_type, mtpc_userStatusOffline); + t_assert(data != nullptr && _type == mtpc_userStatusOffline); split(); return *(MTPDuserStatusOffline*)data; } const MTPDuserStatusOffline &c_userStatusOffline() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_userStatusOffline) throw mtpErrorWrongTypeId(_type, mtpc_userStatusOffline); + t_assert(data != nullptr && _type == mtpc_userStatusOffline); return *(const MTPDuserStatusOffline*)data; } @@ -3349,62 +3255,52 @@ public: } MTPDchatEmpty &_chatEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatEmpty) throw mtpErrorWrongTypeId(_type, mtpc_chatEmpty); + t_assert(data != nullptr && _type == mtpc_chatEmpty); split(); return *(MTPDchatEmpty*)data; } const MTPDchatEmpty &c_chatEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatEmpty) throw mtpErrorWrongTypeId(_type, mtpc_chatEmpty); + t_assert(data != nullptr && _type == mtpc_chatEmpty); return *(const MTPDchatEmpty*)data; } MTPDchat &_chat() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chat) throw mtpErrorWrongTypeId(_type, mtpc_chat); + t_assert(data != nullptr && _type == mtpc_chat); split(); return *(MTPDchat*)data; } const MTPDchat &c_chat() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chat) throw mtpErrorWrongTypeId(_type, mtpc_chat); + t_assert(data != nullptr && _type == mtpc_chat); return *(const MTPDchat*)data; } MTPDchatForbidden &_chatForbidden() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatForbidden) throw mtpErrorWrongTypeId(_type, mtpc_chatForbidden); + t_assert(data != nullptr && _type == mtpc_chatForbidden); split(); return *(MTPDchatForbidden*)data; } const MTPDchatForbidden &c_chatForbidden() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatForbidden) throw mtpErrorWrongTypeId(_type, mtpc_chatForbidden); + t_assert(data != nullptr && _type == mtpc_chatForbidden); return *(const MTPDchatForbidden*)data; } MTPDchannel &_channel() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channel) throw mtpErrorWrongTypeId(_type, mtpc_channel); + t_assert(data != nullptr && _type == mtpc_channel); split(); return *(MTPDchannel*)data; } const MTPDchannel &c_channel() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channel) throw mtpErrorWrongTypeId(_type, mtpc_channel); + t_assert(data != nullptr && _type == mtpc_channel); return *(const MTPDchannel*)data; } MTPDchannelForbidden &_channelForbidden() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelForbidden) throw mtpErrorWrongTypeId(_type, mtpc_channelForbidden); + t_assert(data != nullptr && _type == mtpc_channelForbidden); split(); return *(MTPDchannelForbidden*)data; } const MTPDchannelForbidden &c_channelForbidden() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelForbidden) throw mtpErrorWrongTypeId(_type, mtpc_channelForbidden); + t_assert(data != nullptr && _type == mtpc_channelForbidden); return *(const MTPDchannelForbidden*)data; } @@ -3438,26 +3334,22 @@ public: } MTPDchatFull &_chatFull() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatFull) throw mtpErrorWrongTypeId(_type, mtpc_chatFull); + t_assert(data != nullptr && _type == mtpc_chatFull); split(); return *(MTPDchatFull*)data; } const MTPDchatFull &c_chatFull() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatFull) throw mtpErrorWrongTypeId(_type, mtpc_chatFull); + t_assert(data != nullptr && _type == mtpc_chatFull); return *(const MTPDchatFull*)data; } MTPDchannelFull &_channelFull() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelFull) throw mtpErrorWrongTypeId(_type, mtpc_channelFull); + t_assert(data != nullptr && _type == mtpc_channelFull); split(); return *(MTPDchannelFull*)data; } const MTPDchannelFull &c_channelFull() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelFull) throw mtpErrorWrongTypeId(_type, mtpc_channelFull); + t_assert(data != nullptr && _type == mtpc_channelFull); return *(const MTPDchannelFull*)data; } @@ -3488,38 +3380,32 @@ public: } MTPDchatParticipant &_chatParticipant() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipant) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipant); + t_assert(data != nullptr && _type == mtpc_chatParticipant); split(); return *(MTPDchatParticipant*)data; } const MTPDchatParticipant &c_chatParticipant() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipant) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipant); + t_assert(data != nullptr && _type == mtpc_chatParticipant); return *(const MTPDchatParticipant*)data; } MTPDchatParticipantCreator &_chatParticipantCreator() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipantCreator) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipantCreator); + t_assert(data != nullptr && _type == mtpc_chatParticipantCreator); split(); return *(MTPDchatParticipantCreator*)data; } const MTPDchatParticipantCreator &c_chatParticipantCreator() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipantCreator) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipantCreator); + t_assert(data != nullptr && _type == mtpc_chatParticipantCreator); return *(const MTPDchatParticipantCreator*)data; } MTPDchatParticipantAdmin &_chatParticipantAdmin() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipantAdmin) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipantAdmin); + t_assert(data != nullptr && _type == mtpc_chatParticipantAdmin); split(); return *(MTPDchatParticipantAdmin*)data; } const MTPDchatParticipantAdmin &c_chatParticipantAdmin() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipantAdmin) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipantAdmin); + t_assert(data != nullptr && _type == mtpc_chatParticipantAdmin); return *(const MTPDchatParticipantAdmin*)data; } @@ -3551,26 +3437,22 @@ public: } MTPDchatParticipantsForbidden &_chatParticipantsForbidden() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipantsForbidden) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipantsForbidden); + t_assert(data != nullptr && _type == mtpc_chatParticipantsForbidden); split(); return *(MTPDchatParticipantsForbidden*)data; } const MTPDchatParticipantsForbidden &c_chatParticipantsForbidden() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipantsForbidden) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipantsForbidden); + t_assert(data != nullptr && _type == mtpc_chatParticipantsForbidden); return *(const MTPDchatParticipantsForbidden*)data; } MTPDchatParticipants &_chatParticipants() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipants) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipants); + t_assert(data != nullptr && _type == mtpc_chatParticipants); split(); return *(MTPDchatParticipants*)data; } const MTPDchatParticipants &c_chatParticipants() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatParticipants) throw mtpErrorWrongTypeId(_type, mtpc_chatParticipants); + t_assert(data != nullptr && _type == mtpc_chatParticipants); return *(const MTPDchatParticipants*)data; } @@ -3601,14 +3483,12 @@ public: } MTPDchatPhoto &_chatPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatPhoto) throw mtpErrorWrongTypeId(_type, mtpc_chatPhoto); + t_assert(data != nullptr && _type == mtpc_chatPhoto); split(); return *(MTPDchatPhoto*)data; } const MTPDchatPhoto &c_chatPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatPhoto) throw mtpErrorWrongTypeId(_type, mtpc_chatPhoto); + t_assert(data != nullptr && _type == mtpc_chatPhoto); return *(const MTPDchatPhoto*)data; } @@ -3638,38 +3518,32 @@ public: } MTPDmessageEmpty &_messageEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEmpty) throw mtpErrorWrongTypeId(_type, mtpc_messageEmpty); + t_assert(data != nullptr && _type == mtpc_messageEmpty); split(); return *(MTPDmessageEmpty*)data; } const MTPDmessageEmpty &c_messageEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEmpty) throw mtpErrorWrongTypeId(_type, mtpc_messageEmpty); + t_assert(data != nullptr && _type == mtpc_messageEmpty); return *(const MTPDmessageEmpty*)data; } MTPDmessage &_message() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_message) throw mtpErrorWrongTypeId(_type, mtpc_message); + t_assert(data != nullptr && _type == mtpc_message); split(); return *(MTPDmessage*)data; } const MTPDmessage &c_message() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_message) throw mtpErrorWrongTypeId(_type, mtpc_message); + t_assert(data != nullptr && _type == mtpc_message); return *(const MTPDmessage*)data; } MTPDmessageService &_messageService() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageService) throw mtpErrorWrongTypeId(_type, mtpc_messageService); + t_assert(data != nullptr && _type == mtpc_messageService); split(); return *(MTPDmessageService*)data; } const MTPDmessageService &c_messageService() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageService) throw mtpErrorWrongTypeId(_type, mtpc_messageService); + t_assert(data != nullptr && _type == mtpc_messageService); return *(const MTPDmessageService*)data; } @@ -3701,86 +3575,72 @@ public: } MTPDmessageMediaPhoto &_messageMediaPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaPhoto) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaPhoto); + t_assert(data != nullptr && _type == mtpc_messageMediaPhoto); split(); return *(MTPDmessageMediaPhoto*)data; } const MTPDmessageMediaPhoto &c_messageMediaPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaPhoto) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaPhoto); + t_assert(data != nullptr && _type == mtpc_messageMediaPhoto); return *(const MTPDmessageMediaPhoto*)data; } MTPDmessageMediaGeo &_messageMediaGeo() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaGeo); + t_assert(data != nullptr && _type == mtpc_messageMediaGeo); split(); return *(MTPDmessageMediaGeo*)data; } const MTPDmessageMediaGeo &c_messageMediaGeo() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaGeo); + t_assert(data != nullptr && _type == mtpc_messageMediaGeo); return *(const MTPDmessageMediaGeo*)data; } MTPDmessageMediaContact &_messageMediaContact() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaContact); + t_assert(data != nullptr && _type == mtpc_messageMediaContact); split(); return *(MTPDmessageMediaContact*)data; } const MTPDmessageMediaContact &c_messageMediaContact() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaContact); + t_assert(data != nullptr && _type == mtpc_messageMediaContact); return *(const MTPDmessageMediaContact*)data; } MTPDmessageMediaDocument &_messageMediaDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaDocument); + t_assert(data != nullptr && _type == mtpc_messageMediaDocument); split(); return *(MTPDmessageMediaDocument*)data; } const MTPDmessageMediaDocument &c_messageMediaDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaDocument); + t_assert(data != nullptr && _type == mtpc_messageMediaDocument); return *(const MTPDmessageMediaDocument*)data; } MTPDmessageMediaWebPage &_messageMediaWebPage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaWebPage) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaWebPage); + t_assert(data != nullptr && _type == mtpc_messageMediaWebPage); split(); return *(MTPDmessageMediaWebPage*)data; } const MTPDmessageMediaWebPage &c_messageMediaWebPage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaWebPage) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaWebPage); + t_assert(data != nullptr && _type == mtpc_messageMediaWebPage); return *(const MTPDmessageMediaWebPage*)data; } MTPDmessageMediaVenue &_messageMediaVenue() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaVenue); + t_assert(data != nullptr && _type == mtpc_messageMediaVenue); split(); return *(MTPDmessageMediaVenue*)data; } const MTPDmessageMediaVenue &c_messageMediaVenue() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaVenue); + t_assert(data != nullptr && _type == mtpc_messageMediaVenue); return *(const MTPDmessageMediaVenue*)data; } MTPDmessageMediaGame &_messageMediaGame() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaGame) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaGame); + t_assert(data != nullptr && _type == mtpc_messageMediaGame); split(); return *(MTPDmessageMediaGame*)data; } const MTPDmessageMediaGame &c_messageMediaGame() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageMediaGame) throw mtpErrorWrongTypeId(_type, mtpc_messageMediaGame); + t_assert(data != nullptr && _type == mtpc_messageMediaGame); return *(const MTPDmessageMediaGame*)data; } @@ -3816,122 +3676,102 @@ public: } MTPDmessageActionChatCreate &_messageActionChatCreate() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatCreate) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatCreate); + t_assert(data != nullptr && _type == mtpc_messageActionChatCreate); split(); return *(MTPDmessageActionChatCreate*)data; } const MTPDmessageActionChatCreate &c_messageActionChatCreate() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatCreate) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatCreate); + t_assert(data != nullptr && _type == mtpc_messageActionChatCreate); return *(const MTPDmessageActionChatCreate*)data; } MTPDmessageActionChatEditTitle &_messageActionChatEditTitle() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatEditTitle) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatEditTitle); + t_assert(data != nullptr && _type == mtpc_messageActionChatEditTitle); split(); return *(MTPDmessageActionChatEditTitle*)data; } const MTPDmessageActionChatEditTitle &c_messageActionChatEditTitle() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatEditTitle) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatEditTitle); + t_assert(data != nullptr && _type == mtpc_messageActionChatEditTitle); return *(const MTPDmessageActionChatEditTitle*)data; } MTPDmessageActionChatEditPhoto &_messageActionChatEditPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatEditPhoto) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatEditPhoto); + t_assert(data != nullptr && _type == mtpc_messageActionChatEditPhoto); split(); return *(MTPDmessageActionChatEditPhoto*)data; } const MTPDmessageActionChatEditPhoto &c_messageActionChatEditPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatEditPhoto) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatEditPhoto); + t_assert(data != nullptr && _type == mtpc_messageActionChatEditPhoto); return *(const MTPDmessageActionChatEditPhoto*)data; } MTPDmessageActionChatAddUser &_messageActionChatAddUser() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatAddUser) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatAddUser); + t_assert(data != nullptr && _type == mtpc_messageActionChatAddUser); split(); return *(MTPDmessageActionChatAddUser*)data; } const MTPDmessageActionChatAddUser &c_messageActionChatAddUser() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatAddUser) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatAddUser); + t_assert(data != nullptr && _type == mtpc_messageActionChatAddUser); return *(const MTPDmessageActionChatAddUser*)data; } MTPDmessageActionChatDeleteUser &_messageActionChatDeleteUser() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatDeleteUser) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatDeleteUser); + t_assert(data != nullptr && _type == mtpc_messageActionChatDeleteUser); split(); return *(MTPDmessageActionChatDeleteUser*)data; } const MTPDmessageActionChatDeleteUser &c_messageActionChatDeleteUser() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatDeleteUser) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatDeleteUser); + t_assert(data != nullptr && _type == mtpc_messageActionChatDeleteUser); return *(const MTPDmessageActionChatDeleteUser*)data; } MTPDmessageActionChatJoinedByLink &_messageActionChatJoinedByLink() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatJoinedByLink) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatJoinedByLink); + t_assert(data != nullptr && _type == mtpc_messageActionChatJoinedByLink); split(); return *(MTPDmessageActionChatJoinedByLink*)data; } const MTPDmessageActionChatJoinedByLink &c_messageActionChatJoinedByLink() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatJoinedByLink) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatJoinedByLink); + t_assert(data != nullptr && _type == mtpc_messageActionChatJoinedByLink); return *(const MTPDmessageActionChatJoinedByLink*)data; } MTPDmessageActionChannelCreate &_messageActionChannelCreate() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChannelCreate) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChannelCreate); + t_assert(data != nullptr && _type == mtpc_messageActionChannelCreate); split(); return *(MTPDmessageActionChannelCreate*)data; } const MTPDmessageActionChannelCreate &c_messageActionChannelCreate() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChannelCreate) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChannelCreate); + t_assert(data != nullptr && _type == mtpc_messageActionChannelCreate); return *(const MTPDmessageActionChannelCreate*)data; } MTPDmessageActionChatMigrateTo &_messageActionChatMigrateTo() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatMigrateTo) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatMigrateTo); + t_assert(data != nullptr && _type == mtpc_messageActionChatMigrateTo); split(); return *(MTPDmessageActionChatMigrateTo*)data; } const MTPDmessageActionChatMigrateTo &c_messageActionChatMigrateTo() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChatMigrateTo) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChatMigrateTo); + t_assert(data != nullptr && _type == mtpc_messageActionChatMigrateTo); return *(const MTPDmessageActionChatMigrateTo*)data; } MTPDmessageActionChannelMigrateFrom &_messageActionChannelMigrateFrom() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChannelMigrateFrom) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChannelMigrateFrom); + t_assert(data != nullptr && _type == mtpc_messageActionChannelMigrateFrom); split(); return *(MTPDmessageActionChannelMigrateFrom*)data; } const MTPDmessageActionChannelMigrateFrom &c_messageActionChannelMigrateFrom() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionChannelMigrateFrom) throw mtpErrorWrongTypeId(_type, mtpc_messageActionChannelMigrateFrom); + t_assert(data != nullptr && _type == mtpc_messageActionChannelMigrateFrom); return *(const MTPDmessageActionChannelMigrateFrom*)data; } MTPDmessageActionGameScore &_messageActionGameScore() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionGameScore) throw mtpErrorWrongTypeId(_type, mtpc_messageActionGameScore); + t_assert(data != nullptr && _type == mtpc_messageActionGameScore); split(); return *(MTPDmessageActionGameScore*)data; } const MTPDmessageActionGameScore &c_messageActionGameScore() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageActionGameScore) throw mtpErrorWrongTypeId(_type, mtpc_messageActionGameScore); + t_assert(data != nullptr && _type == mtpc_messageActionGameScore); return *(const MTPDmessageActionGameScore*)data; } @@ -3969,12 +3809,12 @@ public: } MTPDdialog &_dialog() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDdialog*)data; } const MTPDdialog &c_dialog() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDdialog*)data; } @@ -4001,26 +3841,22 @@ public: } MTPDphotoEmpty &_photoEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoEmpty) throw mtpErrorWrongTypeId(_type, mtpc_photoEmpty); + t_assert(data != nullptr && _type == mtpc_photoEmpty); split(); return *(MTPDphotoEmpty*)data; } const MTPDphotoEmpty &c_photoEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoEmpty) throw mtpErrorWrongTypeId(_type, mtpc_photoEmpty); + t_assert(data != nullptr && _type == mtpc_photoEmpty); return *(const MTPDphotoEmpty*)data; } MTPDphoto &_photo() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photo) throw mtpErrorWrongTypeId(_type, mtpc_photo); + t_assert(data != nullptr && _type == mtpc_photo); split(); return *(MTPDphoto*)data; } const MTPDphoto &c_photo() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photo) throw mtpErrorWrongTypeId(_type, mtpc_photo); + t_assert(data != nullptr && _type == mtpc_photo); return *(const MTPDphoto*)data; } @@ -4051,38 +3887,32 @@ public: } MTPDphotoSizeEmpty &_photoSizeEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoSizeEmpty) throw mtpErrorWrongTypeId(_type, mtpc_photoSizeEmpty); + t_assert(data != nullptr && _type == mtpc_photoSizeEmpty); split(); return *(MTPDphotoSizeEmpty*)data; } const MTPDphotoSizeEmpty &c_photoSizeEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoSizeEmpty) throw mtpErrorWrongTypeId(_type, mtpc_photoSizeEmpty); + t_assert(data != nullptr && _type == mtpc_photoSizeEmpty); return *(const MTPDphotoSizeEmpty*)data; } MTPDphotoSize &_photoSize() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoSize) throw mtpErrorWrongTypeId(_type, mtpc_photoSize); + t_assert(data != nullptr && _type == mtpc_photoSize); split(); return *(MTPDphotoSize*)data; } const MTPDphotoSize &c_photoSize() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoSize) throw mtpErrorWrongTypeId(_type, mtpc_photoSize); + t_assert(data != nullptr && _type == mtpc_photoSize); return *(const MTPDphotoSize*)data; } MTPDphotoCachedSize &_photoCachedSize() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoCachedSize) throw mtpErrorWrongTypeId(_type, mtpc_photoCachedSize); + t_assert(data != nullptr && _type == mtpc_photoCachedSize); split(); return *(MTPDphotoCachedSize*)data; } const MTPDphotoCachedSize &c_photoCachedSize() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photoCachedSize) throw mtpErrorWrongTypeId(_type, mtpc_photoCachedSize); + t_assert(data != nullptr && _type == mtpc_photoCachedSize); return *(const MTPDphotoCachedSize*)data; } @@ -4114,14 +3944,12 @@ public: } MTPDgeoPoint &_geoPoint() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_geoPoint) throw mtpErrorWrongTypeId(_type, mtpc_geoPoint); + t_assert(data != nullptr && _type == mtpc_geoPoint); split(); return *(MTPDgeoPoint*)data; } const MTPDgeoPoint &c_geoPoint() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_geoPoint) throw mtpErrorWrongTypeId(_type, mtpc_geoPoint); + t_assert(data != nullptr && _type == mtpc_geoPoint); return *(const MTPDgeoPoint*)data; } @@ -4150,12 +3978,12 @@ public: } MTPDauth_checkedPhone &_auth_checkedPhone() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDauth_checkedPhone*)data; } const MTPDauth_checkedPhone &c_auth_checkedPhone() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDauth_checkedPhone*)data; } @@ -4181,12 +4009,12 @@ public: } MTPDauth_sentCode &_auth_sentCode() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDauth_sentCode*)data; } const MTPDauth_sentCode &c_auth_sentCode() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDauth_sentCode*)data; } @@ -4212,12 +4040,12 @@ public: } MTPDauth_authorization &_auth_authorization() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDauth_authorization*)data; } const MTPDauth_authorization &c_auth_authorization() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDauth_authorization*)data; } @@ -4243,12 +4071,12 @@ public: } MTPDauth_exportedAuthorization &_auth_exportedAuthorization() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDauth_exportedAuthorization*)data; } const MTPDauth_exportedAuthorization &c_auth_exportedAuthorization() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDauth_exportedAuthorization*)data; } @@ -4275,14 +4103,12 @@ public: } MTPDinputNotifyPeer &_inputNotifyPeer() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputNotifyPeer) throw mtpErrorWrongTypeId(_type, mtpc_inputNotifyPeer); + t_assert(data != nullptr && _type == mtpc_inputNotifyPeer); split(); return *(MTPDinputNotifyPeer*)data; } const MTPDinputNotifyPeer &c_inputNotifyPeer() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputNotifyPeer) throw mtpErrorWrongTypeId(_type, mtpc_inputNotifyPeer); + t_assert(data != nullptr && _type == mtpc_inputNotifyPeer); return *(const MTPDinputNotifyPeer*)data; } @@ -4335,12 +4161,12 @@ public: } MTPDinputPeerNotifySettings &_inputPeerNotifySettings() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDinputPeerNotifySettings*)data; } const MTPDinputPeerNotifySettings &c_inputPeerNotifySettings() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDinputPeerNotifySettings*)data; } @@ -4391,14 +4217,12 @@ public: } MTPDpeerNotifySettings &_peerNotifySettings() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerNotifySettings) throw mtpErrorWrongTypeId(_type, mtpc_peerNotifySettings); + t_assert(data != nullptr && _type == mtpc_peerNotifySettings); split(); return *(MTPDpeerNotifySettings*)data; } const MTPDpeerNotifySettings &c_peerNotifySettings() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_peerNotifySettings) throw mtpErrorWrongTypeId(_type, mtpc_peerNotifySettings); + t_assert(data != nullptr && _type == mtpc_peerNotifySettings); return *(const MTPDpeerNotifySettings*)data; } @@ -4427,12 +4251,12 @@ public: } MTPDpeerSettings &_peerSettings() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDpeerSettings*)data; } const MTPDpeerSettings &c_peerSettings() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDpeerSettings*)data; } @@ -4459,26 +4283,22 @@ public: } MTPDwallPaper &_wallPaper() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_wallPaper) throw mtpErrorWrongTypeId(_type, mtpc_wallPaper); + t_assert(data != nullptr && _type == mtpc_wallPaper); split(); return *(MTPDwallPaper*)data; } const MTPDwallPaper &c_wallPaper() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_wallPaper) throw mtpErrorWrongTypeId(_type, mtpc_wallPaper); + t_assert(data != nullptr && _type == mtpc_wallPaper); return *(const MTPDwallPaper*)data; } MTPDwallPaperSolid &_wallPaperSolid() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_wallPaperSolid) throw mtpErrorWrongTypeId(_type, mtpc_wallPaperSolid); + t_assert(data != nullptr && _type == mtpc_wallPaperSolid); split(); return *(MTPDwallPaperSolid*)data; } const MTPDwallPaperSolid &c_wallPaperSolid() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_wallPaperSolid) throw mtpErrorWrongTypeId(_type, mtpc_wallPaperSolid); + t_assert(data != nullptr && _type == mtpc_wallPaperSolid); return *(const MTPDwallPaperSolid*)data; } @@ -4509,14 +4329,12 @@ public: } MTPDinputReportReasonOther &_inputReportReasonOther() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputReportReasonOther) throw mtpErrorWrongTypeId(_type, mtpc_inputReportReasonOther); + t_assert(data != nullptr && _type == mtpc_inputReportReasonOther); split(); return *(MTPDinputReportReasonOther*)data; } const MTPDinputReportReasonOther &c_inputReportReasonOther() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputReportReasonOther) throw mtpErrorWrongTypeId(_type, mtpc_inputReportReasonOther); + t_assert(data != nullptr && _type == mtpc_inputReportReasonOther); return *(const MTPDinputReportReasonOther*)data; } @@ -4545,12 +4363,12 @@ public: } MTPDuserFull &_userFull() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDuserFull*)data; } const MTPDuserFull &c_userFull() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDuserFull*)data; } @@ -4576,12 +4394,12 @@ public: } MTPDcontact &_contact() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontact*)data; } const MTPDcontact &c_contact() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontact*)data; } @@ -4607,12 +4425,12 @@ public: } MTPDimportedContact &_importedContact() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDimportedContact*)data; } const MTPDimportedContact &c_importedContact() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDimportedContact*)data; } @@ -4638,12 +4456,12 @@ public: } MTPDcontactBlocked &_contactBlocked() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontactBlocked*)data; } const MTPDcontactBlocked &c_contactBlocked() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontactBlocked*)data; } @@ -4669,12 +4487,12 @@ public: } MTPDcontactStatus &_contactStatus() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontactStatus*)data; } const MTPDcontactStatus &c_contactStatus() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontactStatus*)data; } @@ -4700,12 +4518,12 @@ public: } MTPDcontacts_link &_contacts_link() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontacts_link*)data; } const MTPDcontacts_link &c_contacts_link() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontacts_link*)data; } @@ -4732,14 +4550,12 @@ public: } MTPDcontacts_contacts &_contacts_contacts() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_contacts) throw mtpErrorWrongTypeId(_type, mtpc_contacts_contacts); + t_assert(data != nullptr && _type == mtpc_contacts_contacts); split(); return *(MTPDcontacts_contacts*)data; } const MTPDcontacts_contacts &c_contacts_contacts() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_contacts) throw mtpErrorWrongTypeId(_type, mtpc_contacts_contacts); + t_assert(data != nullptr && _type == mtpc_contacts_contacts); return *(const MTPDcontacts_contacts*)data; } @@ -4768,12 +4584,12 @@ public: } MTPDcontacts_importedContacts &_contacts_importedContacts() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontacts_importedContacts*)data; } const MTPDcontacts_importedContacts &c_contacts_importedContacts() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontacts_importedContacts*)data; } @@ -4800,26 +4616,22 @@ public: } MTPDcontacts_blocked &_contacts_blocked() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_blocked) throw mtpErrorWrongTypeId(_type, mtpc_contacts_blocked); + t_assert(data != nullptr && _type == mtpc_contacts_blocked); split(); return *(MTPDcontacts_blocked*)data; } const MTPDcontacts_blocked &c_contacts_blocked() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_blocked) throw mtpErrorWrongTypeId(_type, mtpc_contacts_blocked); + t_assert(data != nullptr && _type == mtpc_contacts_blocked); return *(const MTPDcontacts_blocked*)data; } MTPDcontacts_blockedSlice &_contacts_blockedSlice() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_blockedSlice) throw mtpErrorWrongTypeId(_type, mtpc_contacts_blockedSlice); + t_assert(data != nullptr && _type == mtpc_contacts_blockedSlice); split(); return *(MTPDcontacts_blockedSlice*)data; } const MTPDcontacts_blockedSlice &c_contacts_blockedSlice() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_blockedSlice) throw mtpErrorWrongTypeId(_type, mtpc_contacts_blockedSlice); + t_assert(data != nullptr && _type == mtpc_contacts_blockedSlice); return *(const MTPDcontacts_blockedSlice*)data; } @@ -4850,26 +4662,22 @@ public: } MTPDmessages_dialogs &_messages_dialogs() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dialogs) throw mtpErrorWrongTypeId(_type, mtpc_messages_dialogs); + t_assert(data != nullptr && _type == mtpc_messages_dialogs); split(); return *(MTPDmessages_dialogs*)data; } const MTPDmessages_dialogs &c_messages_dialogs() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dialogs) throw mtpErrorWrongTypeId(_type, mtpc_messages_dialogs); + t_assert(data != nullptr && _type == mtpc_messages_dialogs); return *(const MTPDmessages_dialogs*)data; } MTPDmessages_dialogsSlice &_messages_dialogsSlice() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dialogsSlice) throw mtpErrorWrongTypeId(_type, mtpc_messages_dialogsSlice); + t_assert(data != nullptr && _type == mtpc_messages_dialogsSlice); split(); return *(MTPDmessages_dialogsSlice*)data; } const MTPDmessages_dialogsSlice &c_messages_dialogsSlice() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dialogsSlice) throw mtpErrorWrongTypeId(_type, mtpc_messages_dialogsSlice); + t_assert(data != nullptr && _type == mtpc_messages_dialogsSlice); return *(const MTPDmessages_dialogsSlice*)data; } @@ -4900,38 +4708,32 @@ public: } MTPDmessages_messages &_messages_messages() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_messages) throw mtpErrorWrongTypeId(_type, mtpc_messages_messages); + t_assert(data != nullptr && _type == mtpc_messages_messages); split(); return *(MTPDmessages_messages*)data; } const MTPDmessages_messages &c_messages_messages() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_messages) throw mtpErrorWrongTypeId(_type, mtpc_messages_messages); + t_assert(data != nullptr && _type == mtpc_messages_messages); return *(const MTPDmessages_messages*)data; } MTPDmessages_messagesSlice &_messages_messagesSlice() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_messagesSlice) throw mtpErrorWrongTypeId(_type, mtpc_messages_messagesSlice); + t_assert(data != nullptr && _type == mtpc_messages_messagesSlice); split(); return *(MTPDmessages_messagesSlice*)data; } const MTPDmessages_messagesSlice &c_messages_messagesSlice() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_messagesSlice) throw mtpErrorWrongTypeId(_type, mtpc_messages_messagesSlice); + t_assert(data != nullptr && _type == mtpc_messages_messagesSlice); return *(const MTPDmessages_messagesSlice*)data; } MTPDmessages_channelMessages &_messages_channelMessages() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_channelMessages) throw mtpErrorWrongTypeId(_type, mtpc_messages_channelMessages); + t_assert(data != nullptr && _type == mtpc_messages_channelMessages); split(); return *(MTPDmessages_channelMessages*)data; } const MTPDmessages_channelMessages &c_messages_channelMessages() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_channelMessages) throw mtpErrorWrongTypeId(_type, mtpc_messages_channelMessages); + t_assert(data != nullptr && _type == mtpc_messages_channelMessages); return *(const MTPDmessages_channelMessages*)data; } @@ -4962,12 +4764,12 @@ public: } MTPDmessages_chats &_messages_chats() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_chats*)data; } const MTPDmessages_chats &c_messages_chats() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_chats*)data; } @@ -4993,12 +4795,12 @@ public: } MTPDmessages_chatFull &_messages_chatFull() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_chatFull*)data; } const MTPDmessages_chatFull &c_messages_chatFull() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_chatFull*)data; } @@ -5024,12 +4826,12 @@ public: } MTPDmessages_affectedHistory &_messages_affectedHistory() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_affectedHistory*)data; } const MTPDmessages_affectedHistory &c_messages_affectedHistory() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_affectedHistory*)data; } @@ -5080,566 +4882,472 @@ public: } MTPDupdateNewMessage &_updateNewMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewMessage); + t_assert(data != nullptr && _type == mtpc_updateNewMessage); split(); return *(MTPDupdateNewMessage*)data; } const MTPDupdateNewMessage &c_updateNewMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewMessage); + t_assert(data != nullptr && _type == mtpc_updateNewMessage); return *(const MTPDupdateNewMessage*)data; } MTPDupdateMessageID &_updateMessageID() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateMessageID) throw mtpErrorWrongTypeId(_type, mtpc_updateMessageID); + t_assert(data != nullptr && _type == mtpc_updateMessageID); split(); return *(MTPDupdateMessageID*)data; } const MTPDupdateMessageID &c_updateMessageID() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateMessageID) throw mtpErrorWrongTypeId(_type, mtpc_updateMessageID); + t_assert(data != nullptr && _type == mtpc_updateMessageID); return *(const MTPDupdateMessageID*)data; } MTPDupdateDeleteMessages &_updateDeleteMessages() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDeleteMessages) throw mtpErrorWrongTypeId(_type, mtpc_updateDeleteMessages); + t_assert(data != nullptr && _type == mtpc_updateDeleteMessages); split(); return *(MTPDupdateDeleteMessages*)data; } const MTPDupdateDeleteMessages &c_updateDeleteMessages() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDeleteMessages) throw mtpErrorWrongTypeId(_type, mtpc_updateDeleteMessages); + t_assert(data != nullptr && _type == mtpc_updateDeleteMessages); return *(const MTPDupdateDeleteMessages*)data; } MTPDupdateUserTyping &_updateUserTyping() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateUserTyping); + t_assert(data != nullptr && _type == mtpc_updateUserTyping); split(); return *(MTPDupdateUserTyping*)data; } const MTPDupdateUserTyping &c_updateUserTyping() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateUserTyping); + t_assert(data != nullptr && _type == mtpc_updateUserTyping); return *(const MTPDupdateUserTyping*)data; } MTPDupdateChatUserTyping &_updateChatUserTyping() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatUserTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateChatUserTyping); + t_assert(data != nullptr && _type == mtpc_updateChatUserTyping); split(); return *(MTPDupdateChatUserTyping*)data; } const MTPDupdateChatUserTyping &c_updateChatUserTyping() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatUserTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateChatUserTyping); + t_assert(data != nullptr && _type == mtpc_updateChatUserTyping); return *(const MTPDupdateChatUserTyping*)data; } MTPDupdateChatParticipants &_updateChatParticipants() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipants) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipants); + t_assert(data != nullptr && _type == mtpc_updateChatParticipants); split(); return *(MTPDupdateChatParticipants*)data; } const MTPDupdateChatParticipants &c_updateChatParticipants() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipants) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipants); + t_assert(data != nullptr && _type == mtpc_updateChatParticipants); return *(const MTPDupdateChatParticipants*)data; } MTPDupdateUserStatus &_updateUserStatus() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserStatus) throw mtpErrorWrongTypeId(_type, mtpc_updateUserStatus); + t_assert(data != nullptr && _type == mtpc_updateUserStatus); split(); return *(MTPDupdateUserStatus*)data; } const MTPDupdateUserStatus &c_updateUserStatus() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserStatus) throw mtpErrorWrongTypeId(_type, mtpc_updateUserStatus); + t_assert(data != nullptr && _type == mtpc_updateUserStatus); return *(const MTPDupdateUserStatus*)data; } MTPDupdateUserName &_updateUserName() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserName) throw mtpErrorWrongTypeId(_type, mtpc_updateUserName); + t_assert(data != nullptr && _type == mtpc_updateUserName); split(); return *(MTPDupdateUserName*)data; } const MTPDupdateUserName &c_updateUserName() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserName) throw mtpErrorWrongTypeId(_type, mtpc_updateUserName); + t_assert(data != nullptr && _type == mtpc_updateUserName); return *(const MTPDupdateUserName*)data; } MTPDupdateUserPhoto &_updateUserPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserPhoto) throw mtpErrorWrongTypeId(_type, mtpc_updateUserPhoto); + t_assert(data != nullptr && _type == mtpc_updateUserPhoto); split(); return *(MTPDupdateUserPhoto*)data; } const MTPDupdateUserPhoto &c_updateUserPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserPhoto) throw mtpErrorWrongTypeId(_type, mtpc_updateUserPhoto); + t_assert(data != nullptr && _type == mtpc_updateUserPhoto); return *(const MTPDupdateUserPhoto*)data; } MTPDupdateContactRegistered &_updateContactRegistered() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateContactRegistered) throw mtpErrorWrongTypeId(_type, mtpc_updateContactRegistered); + t_assert(data != nullptr && _type == mtpc_updateContactRegistered); split(); return *(MTPDupdateContactRegistered*)data; } const MTPDupdateContactRegistered &c_updateContactRegistered() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateContactRegistered) throw mtpErrorWrongTypeId(_type, mtpc_updateContactRegistered); + t_assert(data != nullptr && _type == mtpc_updateContactRegistered); return *(const MTPDupdateContactRegistered*)data; } MTPDupdateContactLink &_updateContactLink() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateContactLink) throw mtpErrorWrongTypeId(_type, mtpc_updateContactLink); + t_assert(data != nullptr && _type == mtpc_updateContactLink); split(); return *(MTPDupdateContactLink*)data; } const MTPDupdateContactLink &c_updateContactLink() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateContactLink) throw mtpErrorWrongTypeId(_type, mtpc_updateContactLink); + t_assert(data != nullptr && _type == mtpc_updateContactLink); return *(const MTPDupdateContactLink*)data; } MTPDupdateNewAuthorization &_updateNewAuthorization() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewAuthorization) throw mtpErrorWrongTypeId(_type, mtpc_updateNewAuthorization); + t_assert(data != nullptr && _type == mtpc_updateNewAuthorization); split(); return *(MTPDupdateNewAuthorization*)data; } const MTPDupdateNewAuthorization &c_updateNewAuthorization() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewAuthorization) throw mtpErrorWrongTypeId(_type, mtpc_updateNewAuthorization); + t_assert(data != nullptr && _type == mtpc_updateNewAuthorization); return *(const MTPDupdateNewAuthorization*)data; } MTPDupdateNewEncryptedMessage &_updateNewEncryptedMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewEncryptedMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewEncryptedMessage); + t_assert(data != nullptr && _type == mtpc_updateNewEncryptedMessage); split(); return *(MTPDupdateNewEncryptedMessage*)data; } const MTPDupdateNewEncryptedMessage &c_updateNewEncryptedMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewEncryptedMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewEncryptedMessage); + t_assert(data != nullptr && _type == mtpc_updateNewEncryptedMessage); return *(const MTPDupdateNewEncryptedMessage*)data; } MTPDupdateEncryptedChatTyping &_updateEncryptedChatTyping() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEncryptedChatTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateEncryptedChatTyping); + t_assert(data != nullptr && _type == mtpc_updateEncryptedChatTyping); split(); return *(MTPDupdateEncryptedChatTyping*)data; } const MTPDupdateEncryptedChatTyping &c_updateEncryptedChatTyping() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEncryptedChatTyping) throw mtpErrorWrongTypeId(_type, mtpc_updateEncryptedChatTyping); + t_assert(data != nullptr && _type == mtpc_updateEncryptedChatTyping); return *(const MTPDupdateEncryptedChatTyping*)data; } MTPDupdateEncryption &_updateEncryption() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEncryption) throw mtpErrorWrongTypeId(_type, mtpc_updateEncryption); + t_assert(data != nullptr && _type == mtpc_updateEncryption); split(); return *(MTPDupdateEncryption*)data; } const MTPDupdateEncryption &c_updateEncryption() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEncryption) throw mtpErrorWrongTypeId(_type, mtpc_updateEncryption); + t_assert(data != nullptr && _type == mtpc_updateEncryption); return *(const MTPDupdateEncryption*)data; } MTPDupdateEncryptedMessagesRead &_updateEncryptedMessagesRead() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEncryptedMessagesRead) throw mtpErrorWrongTypeId(_type, mtpc_updateEncryptedMessagesRead); + t_assert(data != nullptr && _type == mtpc_updateEncryptedMessagesRead); split(); return *(MTPDupdateEncryptedMessagesRead*)data; } const MTPDupdateEncryptedMessagesRead &c_updateEncryptedMessagesRead() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEncryptedMessagesRead) throw mtpErrorWrongTypeId(_type, mtpc_updateEncryptedMessagesRead); + t_assert(data != nullptr && _type == mtpc_updateEncryptedMessagesRead); return *(const MTPDupdateEncryptedMessagesRead*)data; } MTPDupdateChatParticipantAdd &_updateChatParticipantAdd() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipantAdd) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantAdd); + t_assert(data != nullptr && _type == mtpc_updateChatParticipantAdd); split(); return *(MTPDupdateChatParticipantAdd*)data; } const MTPDupdateChatParticipantAdd &c_updateChatParticipantAdd() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipantAdd) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantAdd); + t_assert(data != nullptr && _type == mtpc_updateChatParticipantAdd); return *(const MTPDupdateChatParticipantAdd*)data; } MTPDupdateChatParticipantDelete &_updateChatParticipantDelete() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipantDelete) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantDelete); + t_assert(data != nullptr && _type == mtpc_updateChatParticipantDelete); split(); return *(MTPDupdateChatParticipantDelete*)data; } const MTPDupdateChatParticipantDelete &c_updateChatParticipantDelete() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipantDelete) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantDelete); + t_assert(data != nullptr && _type == mtpc_updateChatParticipantDelete); return *(const MTPDupdateChatParticipantDelete*)data; } MTPDupdateDcOptions &_updateDcOptions() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDcOptions) throw mtpErrorWrongTypeId(_type, mtpc_updateDcOptions); + t_assert(data != nullptr && _type == mtpc_updateDcOptions); split(); return *(MTPDupdateDcOptions*)data; } const MTPDupdateDcOptions &c_updateDcOptions() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDcOptions) throw mtpErrorWrongTypeId(_type, mtpc_updateDcOptions); + t_assert(data != nullptr && _type == mtpc_updateDcOptions); return *(const MTPDupdateDcOptions*)data; } MTPDupdateUserBlocked &_updateUserBlocked() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserBlocked) throw mtpErrorWrongTypeId(_type, mtpc_updateUserBlocked); + t_assert(data != nullptr && _type == mtpc_updateUserBlocked); split(); return *(MTPDupdateUserBlocked*)data; } const MTPDupdateUserBlocked &c_updateUserBlocked() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserBlocked) throw mtpErrorWrongTypeId(_type, mtpc_updateUserBlocked); + t_assert(data != nullptr && _type == mtpc_updateUserBlocked); return *(const MTPDupdateUserBlocked*)data; } MTPDupdateNotifySettings &_updateNotifySettings() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNotifySettings) throw mtpErrorWrongTypeId(_type, mtpc_updateNotifySettings); + t_assert(data != nullptr && _type == mtpc_updateNotifySettings); split(); return *(MTPDupdateNotifySettings*)data; } const MTPDupdateNotifySettings &c_updateNotifySettings() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNotifySettings) throw mtpErrorWrongTypeId(_type, mtpc_updateNotifySettings); + t_assert(data != nullptr && _type == mtpc_updateNotifySettings); return *(const MTPDupdateNotifySettings*)data; } MTPDupdateServiceNotification &_updateServiceNotification() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateServiceNotification) throw mtpErrorWrongTypeId(_type, mtpc_updateServiceNotification); + t_assert(data != nullptr && _type == mtpc_updateServiceNotification); split(); return *(MTPDupdateServiceNotification*)data; } const MTPDupdateServiceNotification &c_updateServiceNotification() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateServiceNotification) throw mtpErrorWrongTypeId(_type, mtpc_updateServiceNotification); + t_assert(data != nullptr && _type == mtpc_updateServiceNotification); return *(const MTPDupdateServiceNotification*)data; } MTPDupdatePrivacy &_updatePrivacy() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updatePrivacy) throw mtpErrorWrongTypeId(_type, mtpc_updatePrivacy); + t_assert(data != nullptr && _type == mtpc_updatePrivacy); split(); return *(MTPDupdatePrivacy*)data; } const MTPDupdatePrivacy &c_updatePrivacy() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updatePrivacy) throw mtpErrorWrongTypeId(_type, mtpc_updatePrivacy); + t_assert(data != nullptr && _type == mtpc_updatePrivacy); return *(const MTPDupdatePrivacy*)data; } MTPDupdateUserPhone &_updateUserPhone() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserPhone) throw mtpErrorWrongTypeId(_type, mtpc_updateUserPhone); + t_assert(data != nullptr && _type == mtpc_updateUserPhone); split(); return *(MTPDupdateUserPhone*)data; } const MTPDupdateUserPhone &c_updateUserPhone() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateUserPhone) throw mtpErrorWrongTypeId(_type, mtpc_updateUserPhone); + t_assert(data != nullptr && _type == mtpc_updateUserPhone); return *(const MTPDupdateUserPhone*)data; } MTPDupdateReadHistoryInbox &_updateReadHistoryInbox() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadHistoryInbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryInbox); + t_assert(data != nullptr && _type == mtpc_updateReadHistoryInbox); split(); return *(MTPDupdateReadHistoryInbox*)data; } const MTPDupdateReadHistoryInbox &c_updateReadHistoryInbox() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadHistoryInbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryInbox); + t_assert(data != nullptr && _type == mtpc_updateReadHistoryInbox); return *(const MTPDupdateReadHistoryInbox*)data; } MTPDupdateReadHistoryOutbox &_updateReadHistoryOutbox() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadHistoryOutbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryOutbox); + t_assert(data != nullptr && _type == mtpc_updateReadHistoryOutbox); split(); return *(MTPDupdateReadHistoryOutbox*)data; } const MTPDupdateReadHistoryOutbox &c_updateReadHistoryOutbox() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadHistoryOutbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadHistoryOutbox); + t_assert(data != nullptr && _type == mtpc_updateReadHistoryOutbox); return *(const MTPDupdateReadHistoryOutbox*)data; } MTPDupdateWebPage &_updateWebPage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateWebPage) throw mtpErrorWrongTypeId(_type, mtpc_updateWebPage); + t_assert(data != nullptr && _type == mtpc_updateWebPage); split(); return *(MTPDupdateWebPage*)data; } const MTPDupdateWebPage &c_updateWebPage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateWebPage) throw mtpErrorWrongTypeId(_type, mtpc_updateWebPage); + t_assert(data != nullptr && _type == mtpc_updateWebPage); return *(const MTPDupdateWebPage*)data; } MTPDupdateReadMessagesContents &_updateReadMessagesContents() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadMessagesContents) throw mtpErrorWrongTypeId(_type, mtpc_updateReadMessagesContents); + t_assert(data != nullptr && _type == mtpc_updateReadMessagesContents); split(); return *(MTPDupdateReadMessagesContents*)data; } const MTPDupdateReadMessagesContents &c_updateReadMessagesContents() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadMessagesContents) throw mtpErrorWrongTypeId(_type, mtpc_updateReadMessagesContents); + t_assert(data != nullptr && _type == mtpc_updateReadMessagesContents); return *(const MTPDupdateReadMessagesContents*)data; } MTPDupdateChannelTooLong &_updateChannelTooLong() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannelTooLong) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelTooLong); + t_assert(data != nullptr && _type == mtpc_updateChannelTooLong); split(); return *(MTPDupdateChannelTooLong*)data; } const MTPDupdateChannelTooLong &c_updateChannelTooLong() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannelTooLong) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelTooLong); + t_assert(data != nullptr && _type == mtpc_updateChannelTooLong); return *(const MTPDupdateChannelTooLong*)data; } MTPDupdateChannel &_updateChannel() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannel) throw mtpErrorWrongTypeId(_type, mtpc_updateChannel); + t_assert(data != nullptr && _type == mtpc_updateChannel); split(); return *(MTPDupdateChannel*)data; } const MTPDupdateChannel &c_updateChannel() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannel) throw mtpErrorWrongTypeId(_type, mtpc_updateChannel); + t_assert(data != nullptr && _type == mtpc_updateChannel); return *(const MTPDupdateChannel*)data; } MTPDupdateNewChannelMessage &_updateNewChannelMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewChannelMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewChannelMessage); + t_assert(data != nullptr && _type == mtpc_updateNewChannelMessage); split(); return *(MTPDupdateNewChannelMessage*)data; } const MTPDupdateNewChannelMessage &c_updateNewChannelMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewChannelMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateNewChannelMessage); + t_assert(data != nullptr && _type == mtpc_updateNewChannelMessage); return *(const MTPDupdateNewChannelMessage*)data; } MTPDupdateReadChannelInbox &_updateReadChannelInbox() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadChannelInbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadChannelInbox); + t_assert(data != nullptr && _type == mtpc_updateReadChannelInbox); split(); return *(MTPDupdateReadChannelInbox*)data; } const MTPDupdateReadChannelInbox &c_updateReadChannelInbox() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadChannelInbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadChannelInbox); + t_assert(data != nullptr && _type == mtpc_updateReadChannelInbox); return *(const MTPDupdateReadChannelInbox*)data; } MTPDupdateDeleteChannelMessages &_updateDeleteChannelMessages() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDeleteChannelMessages) throw mtpErrorWrongTypeId(_type, mtpc_updateDeleteChannelMessages); + t_assert(data != nullptr && _type == mtpc_updateDeleteChannelMessages); split(); return *(MTPDupdateDeleteChannelMessages*)data; } const MTPDupdateDeleteChannelMessages &c_updateDeleteChannelMessages() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDeleteChannelMessages) throw mtpErrorWrongTypeId(_type, mtpc_updateDeleteChannelMessages); + t_assert(data != nullptr && _type == mtpc_updateDeleteChannelMessages); return *(const MTPDupdateDeleteChannelMessages*)data; } MTPDupdateChannelMessageViews &_updateChannelMessageViews() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannelMessageViews) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelMessageViews); + t_assert(data != nullptr && _type == mtpc_updateChannelMessageViews); split(); return *(MTPDupdateChannelMessageViews*)data; } const MTPDupdateChannelMessageViews &c_updateChannelMessageViews() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannelMessageViews) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelMessageViews); + t_assert(data != nullptr && _type == mtpc_updateChannelMessageViews); return *(const MTPDupdateChannelMessageViews*)data; } MTPDupdateChatAdmins &_updateChatAdmins() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatAdmins) throw mtpErrorWrongTypeId(_type, mtpc_updateChatAdmins); + t_assert(data != nullptr && _type == mtpc_updateChatAdmins); split(); return *(MTPDupdateChatAdmins*)data; } const MTPDupdateChatAdmins &c_updateChatAdmins() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatAdmins) throw mtpErrorWrongTypeId(_type, mtpc_updateChatAdmins); + t_assert(data != nullptr && _type == mtpc_updateChatAdmins); return *(const MTPDupdateChatAdmins*)data; } MTPDupdateChatParticipantAdmin &_updateChatParticipantAdmin() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipantAdmin) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantAdmin); + t_assert(data != nullptr && _type == mtpc_updateChatParticipantAdmin); split(); return *(MTPDupdateChatParticipantAdmin*)data; } const MTPDupdateChatParticipantAdmin &c_updateChatParticipantAdmin() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChatParticipantAdmin) throw mtpErrorWrongTypeId(_type, mtpc_updateChatParticipantAdmin); + t_assert(data != nullptr && _type == mtpc_updateChatParticipantAdmin); return *(const MTPDupdateChatParticipantAdmin*)data; } MTPDupdateNewStickerSet &_updateNewStickerSet() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewStickerSet) throw mtpErrorWrongTypeId(_type, mtpc_updateNewStickerSet); + t_assert(data != nullptr && _type == mtpc_updateNewStickerSet); split(); return *(MTPDupdateNewStickerSet*)data; } const MTPDupdateNewStickerSet &c_updateNewStickerSet() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateNewStickerSet) throw mtpErrorWrongTypeId(_type, mtpc_updateNewStickerSet); + t_assert(data != nullptr && _type == mtpc_updateNewStickerSet); return *(const MTPDupdateNewStickerSet*)data; } MTPDupdateStickerSetsOrder &_updateStickerSetsOrder() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateStickerSetsOrder) throw mtpErrorWrongTypeId(_type, mtpc_updateStickerSetsOrder); + t_assert(data != nullptr && _type == mtpc_updateStickerSetsOrder); split(); return *(MTPDupdateStickerSetsOrder*)data; } const MTPDupdateStickerSetsOrder &c_updateStickerSetsOrder() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateStickerSetsOrder) throw mtpErrorWrongTypeId(_type, mtpc_updateStickerSetsOrder); + t_assert(data != nullptr && _type == mtpc_updateStickerSetsOrder); return *(const MTPDupdateStickerSetsOrder*)data; } MTPDupdateBotInlineQuery &_updateBotInlineQuery() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateBotInlineQuery) throw mtpErrorWrongTypeId(_type, mtpc_updateBotInlineQuery); + t_assert(data != nullptr && _type == mtpc_updateBotInlineQuery); split(); return *(MTPDupdateBotInlineQuery*)data; } const MTPDupdateBotInlineQuery &c_updateBotInlineQuery() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateBotInlineQuery) throw mtpErrorWrongTypeId(_type, mtpc_updateBotInlineQuery); + t_assert(data != nullptr && _type == mtpc_updateBotInlineQuery); return *(const MTPDupdateBotInlineQuery*)data; } MTPDupdateBotInlineSend &_updateBotInlineSend() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateBotInlineSend) throw mtpErrorWrongTypeId(_type, mtpc_updateBotInlineSend); + t_assert(data != nullptr && _type == mtpc_updateBotInlineSend); split(); return *(MTPDupdateBotInlineSend*)data; } const MTPDupdateBotInlineSend &c_updateBotInlineSend() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateBotInlineSend) throw mtpErrorWrongTypeId(_type, mtpc_updateBotInlineSend); + t_assert(data != nullptr && _type == mtpc_updateBotInlineSend); return *(const MTPDupdateBotInlineSend*)data; } MTPDupdateEditChannelMessage &_updateEditChannelMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEditChannelMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateEditChannelMessage); + t_assert(data != nullptr && _type == mtpc_updateEditChannelMessage); split(); return *(MTPDupdateEditChannelMessage*)data; } const MTPDupdateEditChannelMessage &c_updateEditChannelMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEditChannelMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateEditChannelMessage); + t_assert(data != nullptr && _type == mtpc_updateEditChannelMessage); return *(const MTPDupdateEditChannelMessage*)data; } MTPDupdateChannelPinnedMessage &_updateChannelPinnedMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannelPinnedMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelPinnedMessage); + t_assert(data != nullptr && _type == mtpc_updateChannelPinnedMessage); split(); return *(MTPDupdateChannelPinnedMessage*)data; } const MTPDupdateChannelPinnedMessage &c_updateChannelPinnedMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateChannelPinnedMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateChannelPinnedMessage); + t_assert(data != nullptr && _type == mtpc_updateChannelPinnedMessage); return *(const MTPDupdateChannelPinnedMessage*)data; } MTPDupdateBotCallbackQuery &_updateBotCallbackQuery() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateBotCallbackQuery) throw mtpErrorWrongTypeId(_type, mtpc_updateBotCallbackQuery); + t_assert(data != nullptr && _type == mtpc_updateBotCallbackQuery); split(); return *(MTPDupdateBotCallbackQuery*)data; } const MTPDupdateBotCallbackQuery &c_updateBotCallbackQuery() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateBotCallbackQuery) throw mtpErrorWrongTypeId(_type, mtpc_updateBotCallbackQuery); + t_assert(data != nullptr && _type == mtpc_updateBotCallbackQuery); return *(const MTPDupdateBotCallbackQuery*)data; } MTPDupdateEditMessage &_updateEditMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEditMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateEditMessage); + t_assert(data != nullptr && _type == mtpc_updateEditMessage); split(); return *(MTPDupdateEditMessage*)data; } const MTPDupdateEditMessage &c_updateEditMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateEditMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateEditMessage); + t_assert(data != nullptr && _type == mtpc_updateEditMessage); return *(const MTPDupdateEditMessage*)data; } MTPDupdateInlineBotCallbackQuery &_updateInlineBotCallbackQuery() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateInlineBotCallbackQuery) throw mtpErrorWrongTypeId(_type, mtpc_updateInlineBotCallbackQuery); + t_assert(data != nullptr && _type == mtpc_updateInlineBotCallbackQuery); split(); return *(MTPDupdateInlineBotCallbackQuery*)data; } const MTPDupdateInlineBotCallbackQuery &c_updateInlineBotCallbackQuery() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateInlineBotCallbackQuery) throw mtpErrorWrongTypeId(_type, mtpc_updateInlineBotCallbackQuery); + t_assert(data != nullptr && _type == mtpc_updateInlineBotCallbackQuery); return *(const MTPDupdateInlineBotCallbackQuery*)data; } MTPDupdateReadChannelOutbox &_updateReadChannelOutbox() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadChannelOutbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadChannelOutbox); + t_assert(data != nullptr && _type == mtpc_updateReadChannelOutbox); split(); return *(MTPDupdateReadChannelOutbox*)data; } const MTPDupdateReadChannelOutbox &c_updateReadChannelOutbox() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateReadChannelOutbox) throw mtpErrorWrongTypeId(_type, mtpc_updateReadChannelOutbox); + t_assert(data != nullptr && _type == mtpc_updateReadChannelOutbox); return *(const MTPDupdateReadChannelOutbox*)data; } MTPDupdateDraftMessage &_updateDraftMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDraftMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateDraftMessage); + t_assert(data != nullptr && _type == mtpc_updateDraftMessage); split(); return *(MTPDupdateDraftMessage*)data; } const MTPDupdateDraftMessage &c_updateDraftMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateDraftMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateDraftMessage); + t_assert(data != nullptr && _type == mtpc_updateDraftMessage); return *(const MTPDupdateDraftMessage*)data; } @@ -5714,12 +5422,12 @@ public: } MTPDupdates_state &_updates_state() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDupdates_state*)data; } const MTPDupdates_state &c_updates_state() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDupdates_state*)data; } @@ -5746,38 +5454,32 @@ public: } MTPDupdates_differenceEmpty &_updates_differenceEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_differenceEmpty) throw mtpErrorWrongTypeId(_type, mtpc_updates_differenceEmpty); + t_assert(data != nullptr && _type == mtpc_updates_differenceEmpty); split(); return *(MTPDupdates_differenceEmpty*)data; } const MTPDupdates_differenceEmpty &c_updates_differenceEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_differenceEmpty) throw mtpErrorWrongTypeId(_type, mtpc_updates_differenceEmpty); + t_assert(data != nullptr && _type == mtpc_updates_differenceEmpty); return *(const MTPDupdates_differenceEmpty*)data; } MTPDupdates_difference &_updates_difference() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_difference) throw mtpErrorWrongTypeId(_type, mtpc_updates_difference); + t_assert(data != nullptr && _type == mtpc_updates_difference); split(); return *(MTPDupdates_difference*)data; } const MTPDupdates_difference &c_updates_difference() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_difference) throw mtpErrorWrongTypeId(_type, mtpc_updates_difference); + t_assert(data != nullptr && _type == mtpc_updates_difference); return *(const MTPDupdates_difference*)data; } MTPDupdates_differenceSlice &_updates_differenceSlice() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_differenceSlice) throw mtpErrorWrongTypeId(_type, mtpc_updates_differenceSlice); + t_assert(data != nullptr && _type == mtpc_updates_differenceSlice); split(); return *(MTPDupdates_differenceSlice*)data; } const MTPDupdates_differenceSlice &c_updates_differenceSlice() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_differenceSlice) throw mtpErrorWrongTypeId(_type, mtpc_updates_differenceSlice); + t_assert(data != nullptr && _type == mtpc_updates_differenceSlice); return *(const MTPDupdates_differenceSlice*)data; } @@ -5809,74 +5511,62 @@ public: } MTPDupdateShortMessage &_updateShortMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShortMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateShortMessage); + t_assert(data != nullptr && _type == mtpc_updateShortMessage); split(); return *(MTPDupdateShortMessage*)data; } const MTPDupdateShortMessage &c_updateShortMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShortMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateShortMessage); + t_assert(data != nullptr && _type == mtpc_updateShortMessage); return *(const MTPDupdateShortMessage*)data; } MTPDupdateShortChatMessage &_updateShortChatMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShortChatMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateShortChatMessage); + t_assert(data != nullptr && _type == mtpc_updateShortChatMessage); split(); return *(MTPDupdateShortChatMessage*)data; } const MTPDupdateShortChatMessage &c_updateShortChatMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShortChatMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateShortChatMessage); + t_assert(data != nullptr && _type == mtpc_updateShortChatMessage); return *(const MTPDupdateShortChatMessage*)data; } MTPDupdateShort &_updateShort() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShort) throw mtpErrorWrongTypeId(_type, mtpc_updateShort); + t_assert(data != nullptr && _type == mtpc_updateShort); split(); return *(MTPDupdateShort*)data; } const MTPDupdateShort &c_updateShort() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShort) throw mtpErrorWrongTypeId(_type, mtpc_updateShort); + t_assert(data != nullptr && _type == mtpc_updateShort); return *(const MTPDupdateShort*)data; } MTPDupdatesCombined &_updatesCombined() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updatesCombined) throw mtpErrorWrongTypeId(_type, mtpc_updatesCombined); + t_assert(data != nullptr && _type == mtpc_updatesCombined); split(); return *(MTPDupdatesCombined*)data; } const MTPDupdatesCombined &c_updatesCombined() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updatesCombined) throw mtpErrorWrongTypeId(_type, mtpc_updatesCombined); + t_assert(data != nullptr && _type == mtpc_updatesCombined); return *(const MTPDupdatesCombined*)data; } MTPDupdates &_updates() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates) throw mtpErrorWrongTypeId(_type, mtpc_updates); + t_assert(data != nullptr && _type == mtpc_updates); split(); return *(MTPDupdates*)data; } const MTPDupdates &c_updates() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates) throw mtpErrorWrongTypeId(_type, mtpc_updates); + t_assert(data != nullptr && _type == mtpc_updates); return *(const MTPDupdates*)data; } MTPDupdateShortSentMessage &_updateShortSentMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShortSentMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateShortSentMessage); + t_assert(data != nullptr && _type == mtpc_updateShortSentMessage); split(); return *(MTPDupdateShortSentMessage*)data; } const MTPDupdateShortSentMessage &c_updateShortSentMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updateShortSentMessage) throw mtpErrorWrongTypeId(_type, mtpc_updateShortSentMessage); + t_assert(data != nullptr && _type == mtpc_updateShortSentMessage); return *(const MTPDupdateShortSentMessage*)data; } @@ -5911,26 +5601,22 @@ public: } MTPDphotos_photos &_photos_photos() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photos_photos) throw mtpErrorWrongTypeId(_type, mtpc_photos_photos); + t_assert(data != nullptr && _type == mtpc_photos_photos); split(); return *(MTPDphotos_photos*)data; } const MTPDphotos_photos &c_photos_photos() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photos_photos) throw mtpErrorWrongTypeId(_type, mtpc_photos_photos); + t_assert(data != nullptr && _type == mtpc_photos_photos); return *(const MTPDphotos_photos*)data; } MTPDphotos_photosSlice &_photos_photosSlice() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photos_photosSlice) throw mtpErrorWrongTypeId(_type, mtpc_photos_photosSlice); + t_assert(data != nullptr && _type == mtpc_photos_photosSlice); split(); return *(MTPDphotos_photosSlice*)data; } const MTPDphotos_photosSlice &c_photos_photosSlice() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_photos_photosSlice) throw mtpErrorWrongTypeId(_type, mtpc_photos_photosSlice); + t_assert(data != nullptr && _type == mtpc_photos_photosSlice); return *(const MTPDphotos_photosSlice*)data; } @@ -5960,12 +5646,12 @@ public: } MTPDphotos_photo &_photos_photo() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDphotos_photo*)data; } const MTPDphotos_photo &c_photos_photo() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDphotos_photo*)data; } @@ -5991,12 +5677,12 @@ public: } MTPDupload_file &_upload_file() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDupload_file*)data; } const MTPDupload_file &c_upload_file() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDupload_file*)data; } @@ -6022,12 +5708,12 @@ public: } MTPDdcOption &_dcOption() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDdcOption*)data; } const MTPDdcOption &c_dcOption() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDdcOption*)data; } @@ -6053,12 +5739,12 @@ public: } MTPDconfig &_config() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDconfig*)data; } const MTPDconfig &c_config() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDconfig*)data; } @@ -6084,12 +5770,12 @@ public: } MTPDnearestDc &_nearestDc() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDnearestDc*)data; } const MTPDnearestDc &c_nearestDc() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDnearestDc*)data; } @@ -6116,14 +5802,12 @@ public: } MTPDhelp_appUpdate &_help_appUpdate() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_help_appUpdate) throw mtpErrorWrongTypeId(_type, mtpc_help_appUpdate); + t_assert(data != nullptr && _type == mtpc_help_appUpdate); split(); return *(MTPDhelp_appUpdate*)data; } const MTPDhelp_appUpdate &c_help_appUpdate() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_help_appUpdate) throw mtpErrorWrongTypeId(_type, mtpc_help_appUpdate); + t_assert(data != nullptr && _type == mtpc_help_appUpdate); return *(const MTPDhelp_appUpdate*)data; } @@ -6152,12 +5836,12 @@ public: } MTPDhelp_inviteText &_help_inviteText() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDhelp_inviteText*)data; } const MTPDhelp_inviteText &c_help_inviteText() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDhelp_inviteText*)data; } @@ -6184,62 +5868,52 @@ public: } MTPDencryptedChatEmpty &_encryptedChatEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatEmpty) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatEmpty); + t_assert(data != nullptr && _type == mtpc_encryptedChatEmpty); split(); return *(MTPDencryptedChatEmpty*)data; } const MTPDencryptedChatEmpty &c_encryptedChatEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatEmpty) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatEmpty); + t_assert(data != nullptr && _type == mtpc_encryptedChatEmpty); return *(const MTPDencryptedChatEmpty*)data; } MTPDencryptedChatWaiting &_encryptedChatWaiting() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatWaiting) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatWaiting); + t_assert(data != nullptr && _type == mtpc_encryptedChatWaiting); split(); return *(MTPDencryptedChatWaiting*)data; } const MTPDencryptedChatWaiting &c_encryptedChatWaiting() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatWaiting) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatWaiting); + t_assert(data != nullptr && _type == mtpc_encryptedChatWaiting); return *(const MTPDencryptedChatWaiting*)data; } MTPDencryptedChatRequested &_encryptedChatRequested() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatRequested) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatRequested); + t_assert(data != nullptr && _type == mtpc_encryptedChatRequested); split(); return *(MTPDencryptedChatRequested*)data; } const MTPDencryptedChatRequested &c_encryptedChatRequested() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatRequested) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatRequested); + t_assert(data != nullptr && _type == mtpc_encryptedChatRequested); return *(const MTPDencryptedChatRequested*)data; } MTPDencryptedChat &_encryptedChat() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChat) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChat); + t_assert(data != nullptr && _type == mtpc_encryptedChat); split(); return *(MTPDencryptedChat*)data; } const MTPDencryptedChat &c_encryptedChat() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChat) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChat); + t_assert(data != nullptr && _type == mtpc_encryptedChat); return *(const MTPDencryptedChat*)data; } MTPDencryptedChatDiscarded &_encryptedChatDiscarded() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatDiscarded) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatDiscarded); + t_assert(data != nullptr && _type == mtpc_encryptedChatDiscarded); split(); return *(MTPDencryptedChatDiscarded*)data; } const MTPDencryptedChatDiscarded &c_encryptedChatDiscarded() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedChatDiscarded) throw mtpErrorWrongTypeId(_type, mtpc_encryptedChatDiscarded); + t_assert(data != nullptr && _type == mtpc_encryptedChatDiscarded); return *(const MTPDencryptedChatDiscarded*)data; } @@ -6272,12 +5946,12 @@ public: } MTPDinputEncryptedChat &_inputEncryptedChat() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDinputEncryptedChat*)data; } const MTPDinputEncryptedChat &c_inputEncryptedChat() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDinputEncryptedChat*)data; } @@ -6304,14 +5978,12 @@ public: } MTPDencryptedFile &_encryptedFile() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedFile) throw mtpErrorWrongTypeId(_type, mtpc_encryptedFile); + t_assert(data != nullptr && _type == mtpc_encryptedFile); split(); return *(MTPDencryptedFile*)data; } const MTPDencryptedFile &c_encryptedFile() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedFile) throw mtpErrorWrongTypeId(_type, mtpc_encryptedFile); + t_assert(data != nullptr && _type == mtpc_encryptedFile); return *(const MTPDencryptedFile*)data; } @@ -6341,38 +6013,32 @@ public: } MTPDinputEncryptedFileUploaded &_inputEncryptedFileUploaded() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFileUploaded) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileUploaded); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFileUploaded); split(); return *(MTPDinputEncryptedFileUploaded*)data; } const MTPDinputEncryptedFileUploaded &c_inputEncryptedFileUploaded() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFileUploaded) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileUploaded); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFileUploaded); return *(const MTPDinputEncryptedFileUploaded*)data; } MTPDinputEncryptedFile &_inputEncryptedFile() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFile) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFile); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFile); split(); return *(MTPDinputEncryptedFile*)data; } const MTPDinputEncryptedFile &c_inputEncryptedFile() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFile) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFile); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFile); return *(const MTPDinputEncryptedFile*)data; } MTPDinputEncryptedFileBigUploaded &_inputEncryptedFileBigUploaded() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFileBigUploaded) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileBigUploaded); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFileBigUploaded); split(); return *(MTPDinputEncryptedFileBigUploaded*)data; } const MTPDinputEncryptedFileBigUploaded &c_inputEncryptedFileBigUploaded() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputEncryptedFileBigUploaded) throw mtpErrorWrongTypeId(_type, mtpc_inputEncryptedFileBigUploaded); + t_assert(data != nullptr && _type == mtpc_inputEncryptedFileBigUploaded); return *(const MTPDinputEncryptedFileBigUploaded*)data; } @@ -6404,26 +6070,22 @@ public: } MTPDencryptedMessage &_encryptedMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedMessage) throw mtpErrorWrongTypeId(_type, mtpc_encryptedMessage); + t_assert(data != nullptr && _type == mtpc_encryptedMessage); split(); return *(MTPDencryptedMessage*)data; } const MTPDencryptedMessage &c_encryptedMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedMessage) throw mtpErrorWrongTypeId(_type, mtpc_encryptedMessage); + t_assert(data != nullptr && _type == mtpc_encryptedMessage); return *(const MTPDencryptedMessage*)data; } MTPDencryptedMessageService &_encryptedMessageService() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedMessageService) throw mtpErrorWrongTypeId(_type, mtpc_encryptedMessageService); + t_assert(data != nullptr && _type == mtpc_encryptedMessageService); split(); return *(MTPDencryptedMessageService*)data; } const MTPDencryptedMessageService &c_encryptedMessageService() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_encryptedMessageService) throw mtpErrorWrongTypeId(_type, mtpc_encryptedMessageService); + t_assert(data != nullptr && _type == mtpc_encryptedMessageService); return *(const MTPDencryptedMessageService*)data; } @@ -6454,26 +6116,22 @@ public: } MTPDmessages_dhConfigNotModified &_messages_dhConfigNotModified() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dhConfigNotModified) throw mtpErrorWrongTypeId(_type, mtpc_messages_dhConfigNotModified); + t_assert(data != nullptr && _type == mtpc_messages_dhConfigNotModified); split(); return *(MTPDmessages_dhConfigNotModified*)data; } const MTPDmessages_dhConfigNotModified &c_messages_dhConfigNotModified() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dhConfigNotModified) throw mtpErrorWrongTypeId(_type, mtpc_messages_dhConfigNotModified); + t_assert(data != nullptr && _type == mtpc_messages_dhConfigNotModified); return *(const MTPDmessages_dhConfigNotModified*)data; } MTPDmessages_dhConfig &_messages_dhConfig() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dhConfig) throw mtpErrorWrongTypeId(_type, mtpc_messages_dhConfig); + t_assert(data != nullptr && _type == mtpc_messages_dhConfig); split(); return *(MTPDmessages_dhConfig*)data; } const MTPDmessages_dhConfig &c_messages_dhConfig() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_dhConfig) throw mtpErrorWrongTypeId(_type, mtpc_messages_dhConfig); + t_assert(data != nullptr && _type == mtpc_messages_dhConfig); return *(const MTPDmessages_dhConfig*)data; } @@ -6504,26 +6162,22 @@ public: } MTPDmessages_sentEncryptedMessage &_messages_sentEncryptedMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_sentEncryptedMessage) throw mtpErrorWrongTypeId(_type, mtpc_messages_sentEncryptedMessage); + t_assert(data != nullptr && _type == mtpc_messages_sentEncryptedMessage); split(); return *(MTPDmessages_sentEncryptedMessage*)data; } const MTPDmessages_sentEncryptedMessage &c_messages_sentEncryptedMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_sentEncryptedMessage) throw mtpErrorWrongTypeId(_type, mtpc_messages_sentEncryptedMessage); + t_assert(data != nullptr && _type == mtpc_messages_sentEncryptedMessage); return *(const MTPDmessages_sentEncryptedMessage*)data; } MTPDmessages_sentEncryptedFile &_messages_sentEncryptedFile() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_sentEncryptedFile) throw mtpErrorWrongTypeId(_type, mtpc_messages_sentEncryptedFile); + t_assert(data != nullptr && _type == mtpc_messages_sentEncryptedFile); split(); return *(MTPDmessages_sentEncryptedFile*)data; } const MTPDmessages_sentEncryptedFile &c_messages_sentEncryptedFile() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_sentEncryptedFile) throw mtpErrorWrongTypeId(_type, mtpc_messages_sentEncryptedFile); + t_assert(data != nullptr && _type == mtpc_messages_sentEncryptedFile); return *(const MTPDmessages_sentEncryptedFile*)data; } @@ -6554,14 +6208,12 @@ public: } MTPDinputDocument &_inputDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputDocument); + t_assert(data != nullptr && _type == mtpc_inputDocument); split(); return *(MTPDinputDocument*)data; } const MTPDinputDocument &c_inputDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputDocument); + t_assert(data != nullptr && _type == mtpc_inputDocument); return *(const MTPDinputDocument*)data; } @@ -6591,26 +6243,22 @@ public: } MTPDdocumentEmpty &_documentEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentEmpty) throw mtpErrorWrongTypeId(_type, mtpc_documentEmpty); + t_assert(data != nullptr && _type == mtpc_documentEmpty); split(); return *(MTPDdocumentEmpty*)data; } const MTPDdocumentEmpty &c_documentEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentEmpty) throw mtpErrorWrongTypeId(_type, mtpc_documentEmpty); + t_assert(data != nullptr && _type == mtpc_documentEmpty); return *(const MTPDdocumentEmpty*)data; } MTPDdocument &_document() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_document) throw mtpErrorWrongTypeId(_type, mtpc_document); + t_assert(data != nullptr && _type == mtpc_document); split(); return *(MTPDdocument*)data; } const MTPDdocument &c_document() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_document) throw mtpErrorWrongTypeId(_type, mtpc_document); + t_assert(data != nullptr && _type == mtpc_document); return *(const MTPDdocument*)data; } @@ -6640,12 +6288,12 @@ public: } MTPDhelp_support &_help_support() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDhelp_support*)data; } const MTPDhelp_support &c_help_support() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDhelp_support*)data; } @@ -6672,14 +6320,12 @@ public: } MTPDnotifyPeer &_notifyPeer() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_notifyPeer) throw mtpErrorWrongTypeId(_type, mtpc_notifyPeer); + t_assert(data != nullptr && _type == mtpc_notifyPeer); split(); return *(MTPDnotifyPeer*)data; } const MTPDnotifyPeer &c_notifyPeer() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_notifyPeer) throw mtpErrorWrongTypeId(_type, mtpc_notifyPeer); + t_assert(data != nullptr && _type == mtpc_notifyPeer); return *(const MTPDnotifyPeer*)data; } @@ -6709,50 +6355,42 @@ public: } MTPDsendMessageUploadVideoAction &_sendMessageUploadVideoAction() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadVideoAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadVideoAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadVideoAction); split(); return *(MTPDsendMessageUploadVideoAction*)data; } const MTPDsendMessageUploadVideoAction &c_sendMessageUploadVideoAction() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadVideoAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadVideoAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadVideoAction); return *(const MTPDsendMessageUploadVideoAction*)data; } MTPDsendMessageUploadAudioAction &_sendMessageUploadAudioAction() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadAudioAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadAudioAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadAudioAction); split(); return *(MTPDsendMessageUploadAudioAction*)data; } const MTPDsendMessageUploadAudioAction &c_sendMessageUploadAudioAction() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadAudioAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadAudioAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadAudioAction); return *(const MTPDsendMessageUploadAudioAction*)data; } MTPDsendMessageUploadPhotoAction &_sendMessageUploadPhotoAction() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadPhotoAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadPhotoAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadPhotoAction); split(); return *(MTPDsendMessageUploadPhotoAction*)data; } const MTPDsendMessageUploadPhotoAction &c_sendMessageUploadPhotoAction() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadPhotoAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadPhotoAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadPhotoAction); return *(const MTPDsendMessageUploadPhotoAction*)data; } MTPDsendMessageUploadDocumentAction &_sendMessageUploadDocumentAction() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadDocumentAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadDocumentAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadDocumentAction); split(); return *(MTPDsendMessageUploadDocumentAction*)data; } const MTPDsendMessageUploadDocumentAction &c_sendMessageUploadDocumentAction() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_sendMessageUploadDocumentAction) throw mtpErrorWrongTypeId(_type, mtpc_sendMessageUploadDocumentAction); + t_assert(data != nullptr && _type == mtpc_sendMessageUploadDocumentAction); return *(const MTPDsendMessageUploadDocumentAction*)data; } @@ -6784,12 +6422,12 @@ public: } MTPDcontacts_found &_contacts_found() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontacts_found*)data; } const MTPDcontacts_found &c_contacts_found() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontacts_found*)data; } @@ -6864,26 +6502,22 @@ public: } MTPDinputPrivacyValueAllowUsers &_inputPrivacyValueAllowUsers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPrivacyValueAllowUsers) throw mtpErrorWrongTypeId(_type, mtpc_inputPrivacyValueAllowUsers); + t_assert(data != nullptr && _type == mtpc_inputPrivacyValueAllowUsers); split(); return *(MTPDinputPrivacyValueAllowUsers*)data; } const MTPDinputPrivacyValueAllowUsers &c_inputPrivacyValueAllowUsers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPrivacyValueAllowUsers) throw mtpErrorWrongTypeId(_type, mtpc_inputPrivacyValueAllowUsers); + t_assert(data != nullptr && _type == mtpc_inputPrivacyValueAllowUsers); return *(const MTPDinputPrivacyValueAllowUsers*)data; } MTPDinputPrivacyValueDisallowUsers &_inputPrivacyValueDisallowUsers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPrivacyValueDisallowUsers) throw mtpErrorWrongTypeId(_type, mtpc_inputPrivacyValueDisallowUsers); + t_assert(data != nullptr && _type == mtpc_inputPrivacyValueDisallowUsers); split(); return *(MTPDinputPrivacyValueDisallowUsers*)data; } const MTPDinputPrivacyValueDisallowUsers &c_inputPrivacyValueDisallowUsers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputPrivacyValueDisallowUsers) throw mtpErrorWrongTypeId(_type, mtpc_inputPrivacyValueDisallowUsers); + t_assert(data != nullptr && _type == mtpc_inputPrivacyValueDisallowUsers); return *(const MTPDinputPrivacyValueDisallowUsers*)data; } @@ -6914,26 +6548,22 @@ public: } MTPDprivacyValueAllowUsers &_privacyValueAllowUsers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_privacyValueAllowUsers) throw mtpErrorWrongTypeId(_type, mtpc_privacyValueAllowUsers); + t_assert(data != nullptr && _type == mtpc_privacyValueAllowUsers); split(); return *(MTPDprivacyValueAllowUsers*)data; } const MTPDprivacyValueAllowUsers &c_privacyValueAllowUsers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_privacyValueAllowUsers) throw mtpErrorWrongTypeId(_type, mtpc_privacyValueAllowUsers); + t_assert(data != nullptr && _type == mtpc_privacyValueAllowUsers); return *(const MTPDprivacyValueAllowUsers*)data; } MTPDprivacyValueDisallowUsers &_privacyValueDisallowUsers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_privacyValueDisallowUsers) throw mtpErrorWrongTypeId(_type, mtpc_privacyValueDisallowUsers); + t_assert(data != nullptr && _type == mtpc_privacyValueDisallowUsers); split(); return *(MTPDprivacyValueDisallowUsers*)data; } const MTPDprivacyValueDisallowUsers &c_privacyValueDisallowUsers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_privacyValueDisallowUsers) throw mtpErrorWrongTypeId(_type, mtpc_privacyValueDisallowUsers); + t_assert(data != nullptr && _type == mtpc_privacyValueDisallowUsers); return *(const MTPDprivacyValueDisallowUsers*)data; } @@ -6963,12 +6593,12 @@ public: } MTPDaccount_privacyRules &_account_privacyRules() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDaccount_privacyRules*)data; } const MTPDaccount_privacyRules &c_account_privacyRules() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDaccount_privacyRules*)data; } @@ -6994,12 +6624,12 @@ public: } MTPDaccountDaysTTL &_accountDaysTTL() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDaccountDaysTTL*)data; } const MTPDaccountDaysTTL &c_accountDaysTTL() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDaccountDaysTTL*)data; } @@ -7026,62 +6656,52 @@ public: } MTPDdocumentAttributeImageSize &_documentAttributeImageSize() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeImageSize) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeImageSize); + t_assert(data != nullptr && _type == mtpc_documentAttributeImageSize); split(); return *(MTPDdocumentAttributeImageSize*)data; } const MTPDdocumentAttributeImageSize &c_documentAttributeImageSize() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeImageSize) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeImageSize); + t_assert(data != nullptr && _type == mtpc_documentAttributeImageSize); return *(const MTPDdocumentAttributeImageSize*)data; } MTPDdocumentAttributeSticker &_documentAttributeSticker() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeSticker) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeSticker); + t_assert(data != nullptr && _type == mtpc_documentAttributeSticker); split(); return *(MTPDdocumentAttributeSticker*)data; } const MTPDdocumentAttributeSticker &c_documentAttributeSticker() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeSticker) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeSticker); + t_assert(data != nullptr && _type == mtpc_documentAttributeSticker); return *(const MTPDdocumentAttributeSticker*)data; } MTPDdocumentAttributeVideo &_documentAttributeVideo() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeVideo) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeVideo); + t_assert(data != nullptr && _type == mtpc_documentAttributeVideo); split(); return *(MTPDdocumentAttributeVideo*)data; } const MTPDdocumentAttributeVideo &c_documentAttributeVideo() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeVideo) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeVideo); + t_assert(data != nullptr && _type == mtpc_documentAttributeVideo); return *(const MTPDdocumentAttributeVideo*)data; } MTPDdocumentAttributeAudio &_documentAttributeAudio() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeAudio) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeAudio); + t_assert(data != nullptr && _type == mtpc_documentAttributeAudio); split(); return *(MTPDdocumentAttributeAudio*)data; } const MTPDdocumentAttributeAudio &c_documentAttributeAudio() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeAudio) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeAudio); + t_assert(data != nullptr && _type == mtpc_documentAttributeAudio); return *(const MTPDdocumentAttributeAudio*)data; } MTPDdocumentAttributeFilename &_documentAttributeFilename() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeFilename) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeFilename); + t_assert(data != nullptr && _type == mtpc_documentAttributeFilename); split(); return *(MTPDdocumentAttributeFilename*)data; } const MTPDdocumentAttributeFilename &c_documentAttributeFilename() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_documentAttributeFilename) throw mtpErrorWrongTypeId(_type, mtpc_documentAttributeFilename); + t_assert(data != nullptr && _type == mtpc_documentAttributeFilename); return *(const MTPDdocumentAttributeFilename*)data; } @@ -7115,14 +6735,12 @@ public: } MTPDmessages_stickers &_messages_stickers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_stickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_stickers); + t_assert(data != nullptr && _type == mtpc_messages_stickers); split(); return *(MTPDmessages_stickers*)data; } const MTPDmessages_stickers &c_messages_stickers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_stickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_stickers); + t_assert(data != nullptr && _type == mtpc_messages_stickers); return *(const MTPDmessages_stickers*)data; } @@ -7151,12 +6769,12 @@ public: } MTPDstickerPack &_stickerPack() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDstickerPack*)data; } const MTPDstickerPack &c_stickerPack() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDstickerPack*)data; } @@ -7183,14 +6801,12 @@ public: } MTPDmessages_allStickers &_messages_allStickers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_allStickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_allStickers); + t_assert(data != nullptr && _type == mtpc_messages_allStickers); split(); return *(MTPDmessages_allStickers*)data; } const MTPDmessages_allStickers &c_messages_allStickers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_allStickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_allStickers); + t_assert(data != nullptr && _type == mtpc_messages_allStickers); return *(const MTPDmessages_allStickers*)data; } @@ -7219,12 +6835,12 @@ public: } MTPDdisabledFeature &_disabledFeature() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDdisabledFeature*)data; } const MTPDdisabledFeature &c_disabledFeature() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDdisabledFeature*)data; } @@ -7250,12 +6866,12 @@ public: } MTPDmessages_affectedMessages &_messages_affectedMessages() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_affectedMessages*)data; } const MTPDmessages_affectedMessages &c_messages_affectedMessages() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_affectedMessages*)data; } @@ -7306,38 +6922,32 @@ public: } MTPDwebPageEmpty &_webPageEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_webPageEmpty) throw mtpErrorWrongTypeId(_type, mtpc_webPageEmpty); + t_assert(data != nullptr && _type == mtpc_webPageEmpty); split(); return *(MTPDwebPageEmpty*)data; } const MTPDwebPageEmpty &c_webPageEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_webPageEmpty) throw mtpErrorWrongTypeId(_type, mtpc_webPageEmpty); + t_assert(data != nullptr && _type == mtpc_webPageEmpty); return *(const MTPDwebPageEmpty*)data; } MTPDwebPagePending &_webPagePending() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_webPagePending) throw mtpErrorWrongTypeId(_type, mtpc_webPagePending); + t_assert(data != nullptr && _type == mtpc_webPagePending); split(); return *(MTPDwebPagePending*)data; } const MTPDwebPagePending &c_webPagePending() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_webPagePending) throw mtpErrorWrongTypeId(_type, mtpc_webPagePending); + t_assert(data != nullptr && _type == mtpc_webPagePending); return *(const MTPDwebPagePending*)data; } MTPDwebPage &_webPage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_webPage) throw mtpErrorWrongTypeId(_type, mtpc_webPage); + t_assert(data != nullptr && _type == mtpc_webPage); split(); return *(MTPDwebPage*)data; } const MTPDwebPage &c_webPage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_webPage) throw mtpErrorWrongTypeId(_type, mtpc_webPage); + t_assert(data != nullptr && _type == mtpc_webPage); return *(const MTPDwebPage*)data; } @@ -7368,12 +6978,12 @@ public: } MTPDauthorization &_authorization() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDauthorization*)data; } const MTPDauthorization &c_authorization() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDauthorization*)data; } @@ -7399,12 +7009,12 @@ public: } MTPDaccount_authorizations &_account_authorizations() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDaccount_authorizations*)data; } const MTPDaccount_authorizations &c_account_authorizations() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDaccount_authorizations*)data; } @@ -7431,26 +7041,22 @@ public: } MTPDaccount_noPassword &_account_noPassword() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_account_noPassword) throw mtpErrorWrongTypeId(_type, mtpc_account_noPassword); + t_assert(data != nullptr && _type == mtpc_account_noPassword); split(); return *(MTPDaccount_noPassword*)data; } const MTPDaccount_noPassword &c_account_noPassword() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_account_noPassword) throw mtpErrorWrongTypeId(_type, mtpc_account_noPassword); + t_assert(data != nullptr && _type == mtpc_account_noPassword); return *(const MTPDaccount_noPassword*)data; } MTPDaccount_password &_account_password() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_account_password) throw mtpErrorWrongTypeId(_type, mtpc_account_password); + t_assert(data != nullptr && _type == mtpc_account_password); split(); return *(MTPDaccount_password*)data; } const MTPDaccount_password &c_account_password() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_account_password) throw mtpErrorWrongTypeId(_type, mtpc_account_password); + t_assert(data != nullptr && _type == mtpc_account_password); return *(const MTPDaccount_password*)data; } @@ -7480,12 +7086,12 @@ public: } MTPDaccount_passwordSettings &_account_passwordSettings() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDaccount_passwordSettings*)data; } const MTPDaccount_passwordSettings &c_account_passwordSettings() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDaccount_passwordSettings*)data; } @@ -7511,12 +7117,12 @@ public: } MTPDaccount_passwordInputSettings &_account_passwordInputSettings() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDaccount_passwordInputSettings*)data; } const MTPDaccount_passwordInputSettings &c_account_passwordInputSettings() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDaccount_passwordInputSettings*)data; } @@ -7542,12 +7148,12 @@ public: } MTPDauth_passwordRecovery &_auth_passwordRecovery() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDauth_passwordRecovery*)data; } const MTPDauth_passwordRecovery &c_auth_passwordRecovery() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDauth_passwordRecovery*)data; } @@ -7573,12 +7179,12 @@ public: } MTPDreceivedNotifyMessage &_receivedNotifyMessage() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDreceivedNotifyMessage*)data; } const MTPDreceivedNotifyMessage &c_receivedNotifyMessage() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDreceivedNotifyMessage*)data; } @@ -7605,14 +7211,12 @@ public: } MTPDchatInviteExported &_chatInviteExported() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatInviteExported) throw mtpErrorWrongTypeId(_type, mtpc_chatInviteExported); + t_assert(data != nullptr && _type == mtpc_chatInviteExported); split(); return *(MTPDchatInviteExported*)data; } const MTPDchatInviteExported &c_chatInviteExported() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatInviteExported) throw mtpErrorWrongTypeId(_type, mtpc_chatInviteExported); + t_assert(data != nullptr && _type == mtpc_chatInviteExported); return *(const MTPDchatInviteExported*)data; } @@ -7642,26 +7246,22 @@ public: } MTPDchatInviteAlready &_chatInviteAlready() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatInviteAlready) throw mtpErrorWrongTypeId(_type, mtpc_chatInviteAlready); + t_assert(data != nullptr && _type == mtpc_chatInviteAlready); split(); return *(MTPDchatInviteAlready*)data; } const MTPDchatInviteAlready &c_chatInviteAlready() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatInviteAlready) throw mtpErrorWrongTypeId(_type, mtpc_chatInviteAlready); + t_assert(data != nullptr && _type == mtpc_chatInviteAlready); return *(const MTPDchatInviteAlready*)data; } MTPDchatInvite &_chatInvite() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatInvite) throw mtpErrorWrongTypeId(_type, mtpc_chatInvite); + t_assert(data != nullptr && _type == mtpc_chatInvite); split(); return *(MTPDchatInvite*)data; } const MTPDchatInvite &c_chatInvite() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_chatInvite) throw mtpErrorWrongTypeId(_type, mtpc_chatInvite); + t_assert(data != nullptr && _type == mtpc_chatInvite); return *(const MTPDchatInvite*)data; } @@ -7692,26 +7292,22 @@ public: } MTPDinputStickerSetID &_inputStickerSetID() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickerSetID) throw mtpErrorWrongTypeId(_type, mtpc_inputStickerSetID); + t_assert(data != nullptr && _type == mtpc_inputStickerSetID); split(); return *(MTPDinputStickerSetID*)data; } const MTPDinputStickerSetID &c_inputStickerSetID() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickerSetID) throw mtpErrorWrongTypeId(_type, mtpc_inputStickerSetID); + t_assert(data != nullptr && _type == mtpc_inputStickerSetID); return *(const MTPDinputStickerSetID*)data; } MTPDinputStickerSetShortName &_inputStickerSetShortName() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickerSetShortName) throw mtpErrorWrongTypeId(_type, mtpc_inputStickerSetShortName); + t_assert(data != nullptr && _type == mtpc_inputStickerSetShortName); split(); return *(MTPDinputStickerSetShortName*)data; } const MTPDinputStickerSetShortName &c_inputStickerSetShortName() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickerSetShortName) throw mtpErrorWrongTypeId(_type, mtpc_inputStickerSetShortName); + t_assert(data != nullptr && _type == mtpc_inputStickerSetShortName); return *(const MTPDinputStickerSetShortName*)data; } @@ -7741,12 +7337,12 @@ public: } MTPDstickerSet &_stickerSet() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDstickerSet*)data; } const MTPDstickerSet &c_stickerSet() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDstickerSet*)data; } @@ -7772,12 +7368,12 @@ public: } MTPDmessages_stickerSet &_messages_stickerSet() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_stickerSet*)data; } const MTPDmessages_stickerSet &c_messages_stickerSet() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_stickerSet*)data; } @@ -7803,12 +7399,12 @@ public: } MTPDbotCommand &_botCommand() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDbotCommand*)data; } const MTPDbotCommand &c_botCommand() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDbotCommand*)data; } @@ -7834,12 +7430,12 @@ public: } MTPDbotInfo &_botInfo() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDbotInfo*)data; } const MTPDbotInfo &c_botInfo() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDbotInfo*)data; } @@ -7866,86 +7462,72 @@ public: } MTPDkeyboardButton &_keyboardButton() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButton) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButton); + t_assert(data != nullptr && _type == mtpc_keyboardButton); split(); return *(MTPDkeyboardButton*)data; } const MTPDkeyboardButton &c_keyboardButton() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButton) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButton); + t_assert(data != nullptr && _type == mtpc_keyboardButton); return *(const MTPDkeyboardButton*)data; } MTPDkeyboardButtonUrl &_keyboardButtonUrl() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonUrl) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonUrl); + t_assert(data != nullptr && _type == mtpc_keyboardButtonUrl); split(); return *(MTPDkeyboardButtonUrl*)data; } const MTPDkeyboardButtonUrl &c_keyboardButtonUrl() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonUrl) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonUrl); + t_assert(data != nullptr && _type == mtpc_keyboardButtonUrl); return *(const MTPDkeyboardButtonUrl*)data; } MTPDkeyboardButtonCallback &_keyboardButtonCallback() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonCallback) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonCallback); + t_assert(data != nullptr && _type == mtpc_keyboardButtonCallback); split(); return *(MTPDkeyboardButtonCallback*)data; } const MTPDkeyboardButtonCallback &c_keyboardButtonCallback() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonCallback) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonCallback); + t_assert(data != nullptr && _type == mtpc_keyboardButtonCallback); return *(const MTPDkeyboardButtonCallback*)data; } MTPDkeyboardButtonRequestPhone &_keyboardButtonRequestPhone() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonRequestPhone) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonRequestPhone); + t_assert(data != nullptr && _type == mtpc_keyboardButtonRequestPhone); split(); return *(MTPDkeyboardButtonRequestPhone*)data; } const MTPDkeyboardButtonRequestPhone &c_keyboardButtonRequestPhone() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonRequestPhone) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonRequestPhone); + t_assert(data != nullptr && _type == mtpc_keyboardButtonRequestPhone); return *(const MTPDkeyboardButtonRequestPhone*)data; } MTPDkeyboardButtonRequestGeoLocation &_keyboardButtonRequestGeoLocation() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonRequestGeoLocation) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonRequestGeoLocation); + t_assert(data != nullptr && _type == mtpc_keyboardButtonRequestGeoLocation); split(); return *(MTPDkeyboardButtonRequestGeoLocation*)data; } const MTPDkeyboardButtonRequestGeoLocation &c_keyboardButtonRequestGeoLocation() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonRequestGeoLocation) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonRequestGeoLocation); + t_assert(data != nullptr && _type == mtpc_keyboardButtonRequestGeoLocation); return *(const MTPDkeyboardButtonRequestGeoLocation*)data; } MTPDkeyboardButtonSwitchInline &_keyboardButtonSwitchInline() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonSwitchInline) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonSwitchInline); + t_assert(data != nullptr && _type == mtpc_keyboardButtonSwitchInline); split(); return *(MTPDkeyboardButtonSwitchInline*)data; } const MTPDkeyboardButtonSwitchInline &c_keyboardButtonSwitchInline() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonSwitchInline) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonSwitchInline); + t_assert(data != nullptr && _type == mtpc_keyboardButtonSwitchInline); return *(const MTPDkeyboardButtonSwitchInline*)data; } MTPDkeyboardButtonGame &_keyboardButtonGame() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonGame) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonGame); + t_assert(data != nullptr && _type == mtpc_keyboardButtonGame); split(); return *(MTPDkeyboardButtonGame*)data; } const MTPDkeyboardButtonGame &c_keyboardButtonGame() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_keyboardButtonGame) throw mtpErrorWrongTypeId(_type, mtpc_keyboardButtonGame); + t_assert(data != nullptr && _type == mtpc_keyboardButtonGame); return *(const MTPDkeyboardButtonGame*)data; } @@ -7980,12 +7562,12 @@ public: } MTPDkeyboardButtonRow &_keyboardButtonRow() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDkeyboardButtonRow*)data; } const MTPDkeyboardButtonRow &c_keyboardButtonRow() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDkeyboardButtonRow*)data; } @@ -8012,50 +7594,42 @@ public: } MTPDreplyKeyboardHide &_replyKeyboardHide() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyKeyboardHide) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardHide); + t_assert(data != nullptr && _type == mtpc_replyKeyboardHide); split(); return *(MTPDreplyKeyboardHide*)data; } const MTPDreplyKeyboardHide &c_replyKeyboardHide() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyKeyboardHide) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardHide); + t_assert(data != nullptr && _type == mtpc_replyKeyboardHide); return *(const MTPDreplyKeyboardHide*)data; } MTPDreplyKeyboardForceReply &_replyKeyboardForceReply() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyKeyboardForceReply) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardForceReply); + t_assert(data != nullptr && _type == mtpc_replyKeyboardForceReply); split(); return *(MTPDreplyKeyboardForceReply*)data; } const MTPDreplyKeyboardForceReply &c_replyKeyboardForceReply() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyKeyboardForceReply) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardForceReply); + t_assert(data != nullptr && _type == mtpc_replyKeyboardForceReply); return *(const MTPDreplyKeyboardForceReply*)data; } MTPDreplyKeyboardMarkup &_replyKeyboardMarkup() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyKeyboardMarkup) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardMarkup); + t_assert(data != nullptr && _type == mtpc_replyKeyboardMarkup); split(); return *(MTPDreplyKeyboardMarkup*)data; } const MTPDreplyKeyboardMarkup &c_replyKeyboardMarkup() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyKeyboardMarkup) throw mtpErrorWrongTypeId(_type, mtpc_replyKeyboardMarkup); + t_assert(data != nullptr && _type == mtpc_replyKeyboardMarkup); return *(const MTPDreplyKeyboardMarkup*)data; } MTPDreplyInlineMarkup &_replyInlineMarkup() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyInlineMarkup) throw mtpErrorWrongTypeId(_type, mtpc_replyInlineMarkup); + t_assert(data != nullptr && _type == mtpc_replyInlineMarkup); split(); return *(MTPDreplyInlineMarkup*)data; } const MTPDreplyInlineMarkup &c_replyInlineMarkup() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_replyInlineMarkup) throw mtpErrorWrongTypeId(_type, mtpc_replyInlineMarkup); + t_assert(data != nullptr && _type == mtpc_replyInlineMarkup); return *(const MTPDreplyInlineMarkup*)data; } @@ -8088,14 +7662,12 @@ public: } MTPDhelp_appChangelog &_help_appChangelog() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_help_appChangelog) throw mtpErrorWrongTypeId(_type, mtpc_help_appChangelog); + t_assert(data != nullptr && _type == mtpc_help_appChangelog); split(); return *(MTPDhelp_appChangelog*)data; } const MTPDhelp_appChangelog &c_help_appChangelog() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_help_appChangelog) throw mtpErrorWrongTypeId(_type, mtpc_help_appChangelog); + t_assert(data != nullptr && _type == mtpc_help_appChangelog); return *(const MTPDhelp_appChangelog*)data; } @@ -8125,158 +7697,132 @@ public: } MTPDmessageEntityUnknown &_messageEntityUnknown() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityUnknown) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityUnknown); + t_assert(data != nullptr && _type == mtpc_messageEntityUnknown); split(); return *(MTPDmessageEntityUnknown*)data; } const MTPDmessageEntityUnknown &c_messageEntityUnknown() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityUnknown) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityUnknown); + t_assert(data != nullptr && _type == mtpc_messageEntityUnknown); return *(const MTPDmessageEntityUnknown*)data; } MTPDmessageEntityMention &_messageEntityMention() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityMention) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityMention); + t_assert(data != nullptr && _type == mtpc_messageEntityMention); split(); return *(MTPDmessageEntityMention*)data; } const MTPDmessageEntityMention &c_messageEntityMention() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityMention) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityMention); + t_assert(data != nullptr && _type == mtpc_messageEntityMention); return *(const MTPDmessageEntityMention*)data; } MTPDmessageEntityHashtag &_messageEntityHashtag() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityHashtag) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityHashtag); + t_assert(data != nullptr && _type == mtpc_messageEntityHashtag); split(); return *(MTPDmessageEntityHashtag*)data; } const MTPDmessageEntityHashtag &c_messageEntityHashtag() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityHashtag) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityHashtag); + t_assert(data != nullptr && _type == mtpc_messageEntityHashtag); return *(const MTPDmessageEntityHashtag*)data; } MTPDmessageEntityBotCommand &_messageEntityBotCommand() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityBotCommand) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityBotCommand); + t_assert(data != nullptr && _type == mtpc_messageEntityBotCommand); split(); return *(MTPDmessageEntityBotCommand*)data; } const MTPDmessageEntityBotCommand &c_messageEntityBotCommand() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityBotCommand) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityBotCommand); + t_assert(data != nullptr && _type == mtpc_messageEntityBotCommand); return *(const MTPDmessageEntityBotCommand*)data; } MTPDmessageEntityUrl &_messageEntityUrl() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityUrl) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityUrl); + t_assert(data != nullptr && _type == mtpc_messageEntityUrl); split(); return *(MTPDmessageEntityUrl*)data; } const MTPDmessageEntityUrl &c_messageEntityUrl() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityUrl) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityUrl); + t_assert(data != nullptr && _type == mtpc_messageEntityUrl); return *(const MTPDmessageEntityUrl*)data; } MTPDmessageEntityEmail &_messageEntityEmail() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityEmail) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityEmail); + t_assert(data != nullptr && _type == mtpc_messageEntityEmail); split(); return *(MTPDmessageEntityEmail*)data; } const MTPDmessageEntityEmail &c_messageEntityEmail() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityEmail) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityEmail); + t_assert(data != nullptr && _type == mtpc_messageEntityEmail); return *(const MTPDmessageEntityEmail*)data; } MTPDmessageEntityBold &_messageEntityBold() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityBold) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityBold); + t_assert(data != nullptr && _type == mtpc_messageEntityBold); split(); return *(MTPDmessageEntityBold*)data; } const MTPDmessageEntityBold &c_messageEntityBold() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityBold) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityBold); + t_assert(data != nullptr && _type == mtpc_messageEntityBold); return *(const MTPDmessageEntityBold*)data; } MTPDmessageEntityItalic &_messageEntityItalic() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityItalic) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityItalic); + t_assert(data != nullptr && _type == mtpc_messageEntityItalic); split(); return *(MTPDmessageEntityItalic*)data; } const MTPDmessageEntityItalic &c_messageEntityItalic() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityItalic) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityItalic); + t_assert(data != nullptr && _type == mtpc_messageEntityItalic); return *(const MTPDmessageEntityItalic*)data; } MTPDmessageEntityCode &_messageEntityCode() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityCode) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityCode); + t_assert(data != nullptr && _type == mtpc_messageEntityCode); split(); return *(MTPDmessageEntityCode*)data; } const MTPDmessageEntityCode &c_messageEntityCode() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityCode) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityCode); + t_assert(data != nullptr && _type == mtpc_messageEntityCode); return *(const MTPDmessageEntityCode*)data; } MTPDmessageEntityPre &_messageEntityPre() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityPre) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityPre); + t_assert(data != nullptr && _type == mtpc_messageEntityPre); split(); return *(MTPDmessageEntityPre*)data; } const MTPDmessageEntityPre &c_messageEntityPre() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityPre) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityPre); + t_assert(data != nullptr && _type == mtpc_messageEntityPre); return *(const MTPDmessageEntityPre*)data; } MTPDmessageEntityTextUrl &_messageEntityTextUrl() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityTextUrl) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityTextUrl); + t_assert(data != nullptr && _type == mtpc_messageEntityTextUrl); split(); return *(MTPDmessageEntityTextUrl*)data; } const MTPDmessageEntityTextUrl &c_messageEntityTextUrl() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityTextUrl) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityTextUrl); + t_assert(data != nullptr && _type == mtpc_messageEntityTextUrl); return *(const MTPDmessageEntityTextUrl*)data; } MTPDmessageEntityMentionName &_messageEntityMentionName() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityMentionName) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityMentionName); + t_assert(data != nullptr && _type == mtpc_messageEntityMentionName); split(); return *(MTPDmessageEntityMentionName*)data; } const MTPDmessageEntityMentionName &c_messageEntityMentionName() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messageEntityMentionName) throw mtpErrorWrongTypeId(_type, mtpc_messageEntityMentionName); + t_assert(data != nullptr && _type == mtpc_messageEntityMentionName); return *(const MTPDmessageEntityMentionName*)data; } MTPDinputMessageEntityMentionName &_inputMessageEntityMentionName() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMessageEntityMentionName) throw mtpErrorWrongTypeId(_type, mtpc_inputMessageEntityMentionName); + t_assert(data != nullptr && _type == mtpc_inputMessageEntityMentionName); split(); return *(MTPDinputMessageEntityMentionName*)data; } const MTPDinputMessageEntityMentionName &c_inputMessageEntityMentionName() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputMessageEntityMentionName) throw mtpErrorWrongTypeId(_type, mtpc_inputMessageEntityMentionName); + t_assert(data != nullptr && _type == mtpc_inputMessageEntityMentionName); return *(const MTPDinputMessageEntityMentionName*)data; } @@ -8318,14 +7864,12 @@ public: } MTPDinputChannel &_inputChannel() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputChannel) throw mtpErrorWrongTypeId(_type, mtpc_inputChannel); + t_assert(data != nullptr && _type == mtpc_inputChannel); split(); return *(MTPDinputChannel*)data; } const MTPDinputChannel &c_inputChannel() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputChannel) throw mtpErrorWrongTypeId(_type, mtpc_inputChannel); + t_assert(data != nullptr && _type == mtpc_inputChannel); return *(const MTPDinputChannel*)data; } @@ -8354,12 +7898,12 @@ public: } MTPDcontacts_resolvedPeer &_contacts_resolvedPeer() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDcontacts_resolvedPeer*)data; } const MTPDcontacts_resolvedPeer &c_contacts_resolvedPeer() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDcontacts_resolvedPeer*)data; } @@ -8385,12 +7929,12 @@ public: } MTPDmessageRange &_messageRange() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessageRange*)data; } const MTPDmessageRange &c_messageRange() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessageRange*)data; } @@ -8417,38 +7961,32 @@ public: } MTPDupdates_channelDifferenceEmpty &_updates_channelDifferenceEmpty() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_channelDifferenceEmpty) throw mtpErrorWrongTypeId(_type, mtpc_updates_channelDifferenceEmpty); + t_assert(data != nullptr && _type == mtpc_updates_channelDifferenceEmpty); split(); return *(MTPDupdates_channelDifferenceEmpty*)data; } const MTPDupdates_channelDifferenceEmpty &c_updates_channelDifferenceEmpty() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_channelDifferenceEmpty) throw mtpErrorWrongTypeId(_type, mtpc_updates_channelDifferenceEmpty); + t_assert(data != nullptr && _type == mtpc_updates_channelDifferenceEmpty); return *(const MTPDupdates_channelDifferenceEmpty*)data; } MTPDupdates_channelDifferenceTooLong &_updates_channelDifferenceTooLong() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_channelDifferenceTooLong) throw mtpErrorWrongTypeId(_type, mtpc_updates_channelDifferenceTooLong); + t_assert(data != nullptr && _type == mtpc_updates_channelDifferenceTooLong); split(); return *(MTPDupdates_channelDifferenceTooLong*)data; } const MTPDupdates_channelDifferenceTooLong &c_updates_channelDifferenceTooLong() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_channelDifferenceTooLong) throw mtpErrorWrongTypeId(_type, mtpc_updates_channelDifferenceTooLong); + t_assert(data != nullptr && _type == mtpc_updates_channelDifferenceTooLong); return *(const MTPDupdates_channelDifferenceTooLong*)data; } MTPDupdates_channelDifference &_updates_channelDifference() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_channelDifference) throw mtpErrorWrongTypeId(_type, mtpc_updates_channelDifference); + t_assert(data != nullptr && _type == mtpc_updates_channelDifference); split(); return *(MTPDupdates_channelDifference*)data; } const MTPDupdates_channelDifference &c_updates_channelDifference() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_updates_channelDifference) throw mtpErrorWrongTypeId(_type, mtpc_updates_channelDifference); + t_assert(data != nullptr && _type == mtpc_updates_channelDifference); return *(const MTPDupdates_channelDifference*)data; } @@ -8480,14 +8018,12 @@ public: } MTPDchannelMessagesFilter &_channelMessagesFilter() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelMessagesFilter) throw mtpErrorWrongTypeId(_type, mtpc_channelMessagesFilter); + t_assert(data != nullptr && _type == mtpc_channelMessagesFilter); split(); return *(MTPDchannelMessagesFilter*)data; } const MTPDchannelMessagesFilter &c_channelMessagesFilter() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelMessagesFilter) throw mtpErrorWrongTypeId(_type, mtpc_channelMessagesFilter); + t_assert(data != nullptr && _type == mtpc_channelMessagesFilter); return *(const MTPDchannelMessagesFilter*)data; } @@ -8517,74 +8053,62 @@ public: } MTPDchannelParticipant &_channelParticipant() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipant) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipant); + t_assert(data != nullptr && _type == mtpc_channelParticipant); split(); return *(MTPDchannelParticipant*)data; } const MTPDchannelParticipant &c_channelParticipant() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipant) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipant); + t_assert(data != nullptr && _type == mtpc_channelParticipant); return *(const MTPDchannelParticipant*)data; } MTPDchannelParticipantSelf &_channelParticipantSelf() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantSelf) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantSelf); + t_assert(data != nullptr && _type == mtpc_channelParticipantSelf); split(); return *(MTPDchannelParticipantSelf*)data; } const MTPDchannelParticipantSelf &c_channelParticipantSelf() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantSelf) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantSelf); + t_assert(data != nullptr && _type == mtpc_channelParticipantSelf); return *(const MTPDchannelParticipantSelf*)data; } MTPDchannelParticipantModerator &_channelParticipantModerator() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantModerator) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantModerator); + t_assert(data != nullptr && _type == mtpc_channelParticipantModerator); split(); return *(MTPDchannelParticipantModerator*)data; } const MTPDchannelParticipantModerator &c_channelParticipantModerator() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantModerator) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantModerator); + t_assert(data != nullptr && _type == mtpc_channelParticipantModerator); return *(const MTPDchannelParticipantModerator*)data; } MTPDchannelParticipantEditor &_channelParticipantEditor() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantEditor) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantEditor); + t_assert(data != nullptr && _type == mtpc_channelParticipantEditor); split(); return *(MTPDchannelParticipantEditor*)data; } const MTPDchannelParticipantEditor &c_channelParticipantEditor() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantEditor) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantEditor); + t_assert(data != nullptr && _type == mtpc_channelParticipantEditor); return *(const MTPDchannelParticipantEditor*)data; } MTPDchannelParticipantKicked &_channelParticipantKicked() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantKicked) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantKicked); + t_assert(data != nullptr && _type == mtpc_channelParticipantKicked); split(); return *(MTPDchannelParticipantKicked*)data; } const MTPDchannelParticipantKicked &c_channelParticipantKicked() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantKicked) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantKicked); + t_assert(data != nullptr && _type == mtpc_channelParticipantKicked); return *(const MTPDchannelParticipantKicked*)data; } MTPDchannelParticipantCreator &_channelParticipantCreator() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantCreator) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantCreator); + t_assert(data != nullptr && _type == mtpc_channelParticipantCreator); split(); return *(MTPDchannelParticipantCreator*)data; } const MTPDchannelParticipantCreator &c_channelParticipantCreator() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_channelParticipantCreator) throw mtpErrorWrongTypeId(_type, mtpc_channelParticipantCreator); + t_assert(data != nullptr && _type == mtpc_channelParticipantCreator); return *(const MTPDchannelParticipantCreator*)data; } @@ -8666,12 +8190,12 @@ public: } MTPDchannels_channelParticipants &_channels_channelParticipants() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDchannels_channelParticipants*)data; } const MTPDchannels_channelParticipants &c_channels_channelParticipants() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDchannels_channelParticipants*)data; } @@ -8697,12 +8221,12 @@ public: } MTPDchannels_channelParticipant &_channels_channelParticipant() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDchannels_channelParticipant*)data; } const MTPDchannels_channelParticipant &c_channels_channelParticipant() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDchannels_channelParticipant*)data; } @@ -8728,12 +8252,12 @@ public: } MTPDhelp_termsOfService &_help_termsOfService() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDhelp_termsOfService*)data; } const MTPDhelp_termsOfService &c_help_termsOfService() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDhelp_termsOfService*)data; } @@ -8760,26 +8284,22 @@ public: } MTPDfoundGif &_foundGif() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_foundGif) throw mtpErrorWrongTypeId(_type, mtpc_foundGif); + t_assert(data != nullptr && _type == mtpc_foundGif); split(); return *(MTPDfoundGif*)data; } const MTPDfoundGif &c_foundGif() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_foundGif) throw mtpErrorWrongTypeId(_type, mtpc_foundGif); + t_assert(data != nullptr && _type == mtpc_foundGif); return *(const MTPDfoundGif*)data; } MTPDfoundGifCached &_foundGifCached() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_foundGifCached) throw mtpErrorWrongTypeId(_type, mtpc_foundGifCached); + t_assert(data != nullptr && _type == mtpc_foundGifCached); split(); return *(MTPDfoundGifCached*)data; } const MTPDfoundGifCached &c_foundGifCached() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_foundGifCached) throw mtpErrorWrongTypeId(_type, mtpc_foundGifCached); + t_assert(data != nullptr && _type == mtpc_foundGifCached); return *(const MTPDfoundGifCached*)data; } @@ -8809,12 +8329,12 @@ public: } MTPDmessages_foundGifs &_messages_foundGifs() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_foundGifs*)data; } const MTPDmessages_foundGifs &c_messages_foundGifs() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_foundGifs*)data; } @@ -8841,14 +8361,12 @@ public: } MTPDmessages_savedGifs &_messages_savedGifs() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_savedGifs) throw mtpErrorWrongTypeId(_type, mtpc_messages_savedGifs); + t_assert(data != nullptr && _type == mtpc_messages_savedGifs); split(); return *(MTPDmessages_savedGifs*)data; } const MTPDmessages_savedGifs &c_messages_savedGifs() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_savedGifs) throw mtpErrorWrongTypeId(_type, mtpc_messages_savedGifs); + t_assert(data != nullptr && _type == mtpc_messages_savedGifs); return *(const MTPDmessages_savedGifs*)data; } @@ -8878,74 +8396,62 @@ public: } MTPDinputBotInlineMessageMediaAuto &_inputBotInlineMessageMediaAuto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaAuto) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaAuto); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaAuto); split(); return *(MTPDinputBotInlineMessageMediaAuto*)data; } const MTPDinputBotInlineMessageMediaAuto &c_inputBotInlineMessageMediaAuto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaAuto) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaAuto); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaAuto); return *(const MTPDinputBotInlineMessageMediaAuto*)data; } MTPDinputBotInlineMessageText &_inputBotInlineMessageText() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageText) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageText); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageText); split(); return *(MTPDinputBotInlineMessageText*)data; } const MTPDinputBotInlineMessageText &c_inputBotInlineMessageText() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageText) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageText); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageText); return *(const MTPDinputBotInlineMessageText*)data; } MTPDinputBotInlineMessageMediaGeo &_inputBotInlineMessageMediaGeo() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaGeo); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaGeo); split(); return *(MTPDinputBotInlineMessageMediaGeo*)data; } const MTPDinputBotInlineMessageMediaGeo &c_inputBotInlineMessageMediaGeo() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaGeo); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaGeo); return *(const MTPDinputBotInlineMessageMediaGeo*)data; } MTPDinputBotInlineMessageMediaVenue &_inputBotInlineMessageMediaVenue() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaVenue); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaVenue); split(); return *(MTPDinputBotInlineMessageMediaVenue*)data; } const MTPDinputBotInlineMessageMediaVenue &c_inputBotInlineMessageMediaVenue() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaVenue); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaVenue); return *(const MTPDinputBotInlineMessageMediaVenue*)data; } MTPDinputBotInlineMessageMediaContact &_inputBotInlineMessageMediaContact() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaContact); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaContact); split(); return *(MTPDinputBotInlineMessageMediaContact*)data; } const MTPDinputBotInlineMessageMediaContact &c_inputBotInlineMessageMediaContact() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageMediaContact); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageMediaContact); return *(const MTPDinputBotInlineMessageMediaContact*)data; } MTPDinputBotInlineMessageGame &_inputBotInlineMessageGame() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageGame) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageGame); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageGame); split(); return *(MTPDinputBotInlineMessageGame*)data; } const MTPDinputBotInlineMessageGame &c_inputBotInlineMessageGame() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineMessageGame) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineMessageGame); + t_assert(data != nullptr && _type == mtpc_inputBotInlineMessageGame); return *(const MTPDinputBotInlineMessageGame*)data; } @@ -8980,50 +8486,42 @@ public: } MTPDinputBotInlineResult &_inputBotInlineResult() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResult) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResult); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResult); split(); return *(MTPDinputBotInlineResult*)data; } const MTPDinputBotInlineResult &c_inputBotInlineResult() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResult) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResult); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResult); return *(const MTPDinputBotInlineResult*)data; } MTPDinputBotInlineResultPhoto &_inputBotInlineResultPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResultPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResultPhoto); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResultPhoto); split(); return *(MTPDinputBotInlineResultPhoto*)data; } const MTPDinputBotInlineResultPhoto &c_inputBotInlineResultPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResultPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResultPhoto); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResultPhoto); return *(const MTPDinputBotInlineResultPhoto*)data; } MTPDinputBotInlineResultDocument &_inputBotInlineResultDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResultDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResultDocument); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResultDocument); split(); return *(MTPDinputBotInlineResultDocument*)data; } const MTPDinputBotInlineResultDocument &c_inputBotInlineResultDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResultDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResultDocument); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResultDocument); return *(const MTPDinputBotInlineResultDocument*)data; } MTPDinputBotInlineResultGame &_inputBotInlineResultGame() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResultGame) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResultGame); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResultGame); split(); return *(MTPDinputBotInlineResultGame*)data; } const MTPDinputBotInlineResultGame &c_inputBotInlineResultGame() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputBotInlineResultGame) throw mtpErrorWrongTypeId(_type, mtpc_inputBotInlineResultGame); + t_assert(data != nullptr && _type == mtpc_inputBotInlineResultGame); return *(const MTPDinputBotInlineResultGame*)data; } @@ -9056,62 +8554,52 @@ public: } MTPDbotInlineMessageMediaAuto &_botInlineMessageMediaAuto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaAuto) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaAuto); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaAuto); split(); return *(MTPDbotInlineMessageMediaAuto*)data; } const MTPDbotInlineMessageMediaAuto &c_botInlineMessageMediaAuto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaAuto) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaAuto); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaAuto); return *(const MTPDbotInlineMessageMediaAuto*)data; } MTPDbotInlineMessageText &_botInlineMessageText() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageText) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageText); + t_assert(data != nullptr && _type == mtpc_botInlineMessageText); split(); return *(MTPDbotInlineMessageText*)data; } const MTPDbotInlineMessageText &c_botInlineMessageText() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageText) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageText); + t_assert(data != nullptr && _type == mtpc_botInlineMessageText); return *(const MTPDbotInlineMessageText*)data; } MTPDbotInlineMessageMediaGeo &_botInlineMessageMediaGeo() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaGeo); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaGeo); split(); return *(MTPDbotInlineMessageMediaGeo*)data; } const MTPDbotInlineMessageMediaGeo &c_botInlineMessageMediaGeo() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaGeo) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaGeo); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaGeo); return *(const MTPDbotInlineMessageMediaGeo*)data; } MTPDbotInlineMessageMediaVenue &_botInlineMessageMediaVenue() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaVenue); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaVenue); split(); return *(MTPDbotInlineMessageMediaVenue*)data; } const MTPDbotInlineMessageMediaVenue &c_botInlineMessageMediaVenue() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaVenue) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaVenue); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaVenue); return *(const MTPDbotInlineMessageMediaVenue*)data; } MTPDbotInlineMessageMediaContact &_botInlineMessageMediaContact() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaContact); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaContact); split(); return *(MTPDbotInlineMessageMediaContact*)data; } const MTPDbotInlineMessageMediaContact &c_botInlineMessageMediaContact() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMessageMediaContact) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMessageMediaContact); + t_assert(data != nullptr && _type == mtpc_botInlineMessageMediaContact); return *(const MTPDbotInlineMessageMediaContact*)data; } @@ -9145,26 +8633,22 @@ public: } MTPDbotInlineResult &_botInlineResult() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineResult) throw mtpErrorWrongTypeId(_type, mtpc_botInlineResult); + t_assert(data != nullptr && _type == mtpc_botInlineResult); split(); return *(MTPDbotInlineResult*)data; } const MTPDbotInlineResult &c_botInlineResult() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineResult) throw mtpErrorWrongTypeId(_type, mtpc_botInlineResult); + t_assert(data != nullptr && _type == mtpc_botInlineResult); return *(const MTPDbotInlineResult*)data; } MTPDbotInlineMediaResult &_botInlineMediaResult() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMediaResult) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMediaResult); + t_assert(data != nullptr && _type == mtpc_botInlineMediaResult); split(); return *(MTPDbotInlineMediaResult*)data; } const MTPDbotInlineMediaResult &c_botInlineMediaResult() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_botInlineMediaResult) throw mtpErrorWrongTypeId(_type, mtpc_botInlineMediaResult); + t_assert(data != nullptr && _type == mtpc_botInlineMediaResult); return *(const MTPDbotInlineMediaResult*)data; } @@ -9194,12 +8678,12 @@ public: } MTPDmessages_botResults &_messages_botResults() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_botResults*)data; } const MTPDmessages_botResults &c_messages_botResults() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_botResults*)data; } @@ -9225,12 +8709,12 @@ public: } MTPDexportedMessageLink &_exportedMessageLink() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDexportedMessageLink*)data; } const MTPDexportedMessageLink &c_exportedMessageLink() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDexportedMessageLink*)data; } @@ -9256,12 +8740,12 @@ public: } MTPDmessageFwdHeader &_messageFwdHeader() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessageFwdHeader*)data; } const MTPDmessageFwdHeader &c_messageFwdHeader() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessageFwdHeader*)data; } @@ -9312,50 +8796,42 @@ public: } MTPDauth_sentCodeTypeApp &_auth_sentCodeTypeApp() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeApp) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeApp); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeApp); split(); return *(MTPDauth_sentCodeTypeApp*)data; } const MTPDauth_sentCodeTypeApp &c_auth_sentCodeTypeApp() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeApp) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeApp); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeApp); return *(const MTPDauth_sentCodeTypeApp*)data; } MTPDauth_sentCodeTypeSms &_auth_sentCodeTypeSms() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeSms) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeSms); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeSms); split(); return *(MTPDauth_sentCodeTypeSms*)data; } const MTPDauth_sentCodeTypeSms &c_auth_sentCodeTypeSms() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeSms) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeSms); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeSms); return *(const MTPDauth_sentCodeTypeSms*)data; } MTPDauth_sentCodeTypeCall &_auth_sentCodeTypeCall() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeCall) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeCall); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeCall); split(); return *(MTPDauth_sentCodeTypeCall*)data; } const MTPDauth_sentCodeTypeCall &c_auth_sentCodeTypeCall() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeCall) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeCall); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeCall); return *(const MTPDauth_sentCodeTypeCall*)data; } MTPDauth_sentCodeTypeFlashCall &_auth_sentCodeTypeFlashCall() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeFlashCall) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeFlashCall); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeFlashCall); split(); return *(MTPDauth_sentCodeTypeFlashCall*)data; } const MTPDauth_sentCodeTypeFlashCall &c_auth_sentCodeTypeFlashCall() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_auth_sentCodeTypeFlashCall) throw mtpErrorWrongTypeId(_type, mtpc_auth_sentCodeTypeFlashCall); + t_assert(data != nullptr && _type == mtpc_auth_sentCodeTypeFlashCall); return *(const MTPDauth_sentCodeTypeFlashCall*)data; } @@ -9387,12 +8863,12 @@ public: } MTPDmessages_botCallbackAnswer &_messages_botCallbackAnswer() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_botCallbackAnswer*)data; } const MTPDmessages_botCallbackAnswer &c_messages_botCallbackAnswer() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_botCallbackAnswer*)data; } @@ -9418,12 +8894,12 @@ public: } MTPDmessages_messageEditData &_messages_messageEditData() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_messageEditData*)data; } const MTPDmessages_messageEditData &c_messages_messageEditData() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_messageEditData*)data; } @@ -9449,12 +8925,12 @@ public: } MTPDinputBotInlineMessageID &_inputBotInlineMessageID() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDinputBotInlineMessageID*)data; } const MTPDinputBotInlineMessageID &c_inputBotInlineMessageID() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDinputBotInlineMessageID*)data; } @@ -9480,12 +8956,12 @@ public: } MTPDinlineBotSwitchPM &_inlineBotSwitchPM() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDinlineBotSwitchPM*)data; } const MTPDinlineBotSwitchPM &c_inlineBotSwitchPM() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDinlineBotSwitchPM*)data; } @@ -9511,12 +8987,12 @@ public: } MTPDmessages_peerDialogs &_messages_peerDialogs() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_peerDialogs*)data; } const MTPDmessages_peerDialogs &c_messages_peerDialogs() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_peerDialogs*)data; } @@ -9542,12 +9018,12 @@ public: } MTPDtopPeer &_topPeer() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDtopPeer*)data; } const MTPDtopPeer &c_topPeer() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDtopPeer*)data; } @@ -9597,12 +9073,12 @@ public: } MTPDtopPeerCategoryPeers &_topPeerCategoryPeers() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDtopPeerCategoryPeers*)data; } const MTPDtopPeerCategoryPeers &c_topPeerCategoryPeers() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDtopPeerCategoryPeers*)data; } @@ -9629,14 +9105,12 @@ public: } MTPDcontacts_topPeers &_contacts_topPeers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_topPeers) throw mtpErrorWrongTypeId(_type, mtpc_contacts_topPeers); + t_assert(data != nullptr && _type == mtpc_contacts_topPeers); split(); return *(MTPDcontacts_topPeers*)data; } const MTPDcontacts_topPeers &c_contacts_topPeers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_contacts_topPeers) throw mtpErrorWrongTypeId(_type, mtpc_contacts_topPeers); + t_assert(data != nullptr && _type == mtpc_contacts_topPeers); return *(const MTPDcontacts_topPeers*)data; } @@ -9666,14 +9140,12 @@ public: } MTPDdraftMessage &_draftMessage() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_draftMessage) throw mtpErrorWrongTypeId(_type, mtpc_draftMessage); + t_assert(data != nullptr && _type == mtpc_draftMessage); split(); return *(MTPDdraftMessage*)data; } const MTPDdraftMessage &c_draftMessage() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_draftMessage) throw mtpErrorWrongTypeId(_type, mtpc_draftMessage); + t_assert(data != nullptr && _type == mtpc_draftMessage); return *(const MTPDdraftMessage*)data; } @@ -9703,14 +9175,12 @@ public: } MTPDmessages_featuredStickers &_messages_featuredStickers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_featuredStickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_featuredStickers); + t_assert(data != nullptr && _type == mtpc_messages_featuredStickers); split(); return *(MTPDmessages_featuredStickers*)data; } const MTPDmessages_featuredStickers &c_messages_featuredStickers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_featuredStickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_featuredStickers); + t_assert(data != nullptr && _type == mtpc_messages_featuredStickers); return *(const MTPDmessages_featuredStickers*)data; } @@ -9740,14 +9210,12 @@ public: } MTPDmessages_recentStickers &_messages_recentStickers() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_recentStickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_recentStickers); + t_assert(data != nullptr && _type == mtpc_messages_recentStickers); split(); return *(MTPDmessages_recentStickers*)data; } const MTPDmessages_recentStickers &c_messages_recentStickers() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_recentStickers) throw mtpErrorWrongTypeId(_type, mtpc_messages_recentStickers); + t_assert(data != nullptr && _type == mtpc_messages_recentStickers); return *(const MTPDmessages_recentStickers*)data; } @@ -9776,12 +9244,12 @@ public: } MTPDmessages_archivedStickers &_messages_archivedStickers() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_archivedStickers*)data; } const MTPDmessages_archivedStickers &c_messages_archivedStickers() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_archivedStickers*)data; } @@ -9808,14 +9276,12 @@ public: } MTPDmessages_stickerSetInstallResultArchive &_messages_stickerSetInstallResultArchive() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_stickerSetInstallResultArchive) throw mtpErrorWrongTypeId(_type, mtpc_messages_stickerSetInstallResultArchive); + t_assert(data != nullptr && _type == mtpc_messages_stickerSetInstallResultArchive); split(); return *(MTPDmessages_stickerSetInstallResultArchive*)data; } const MTPDmessages_stickerSetInstallResultArchive &c_messages_stickerSetInstallResultArchive() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_messages_stickerSetInstallResultArchive) throw mtpErrorWrongTypeId(_type, mtpc_messages_stickerSetInstallResultArchive); + t_assert(data != nullptr && _type == mtpc_messages_stickerSetInstallResultArchive); return *(const MTPDmessages_stickerSetInstallResultArchive*)data; } @@ -9845,26 +9311,22 @@ public: } MTPDstickerSetCovered &_stickerSetCovered() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_stickerSetCovered) throw mtpErrorWrongTypeId(_type, mtpc_stickerSetCovered); + t_assert(data != nullptr && _type == mtpc_stickerSetCovered); split(); return *(MTPDstickerSetCovered*)data; } const MTPDstickerSetCovered &c_stickerSetCovered() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_stickerSetCovered) throw mtpErrorWrongTypeId(_type, mtpc_stickerSetCovered); + t_assert(data != nullptr && _type == mtpc_stickerSetCovered); return *(const MTPDstickerSetCovered*)data; } MTPDstickerSetMultiCovered &_stickerSetMultiCovered() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_stickerSetMultiCovered) throw mtpErrorWrongTypeId(_type, mtpc_stickerSetMultiCovered); + t_assert(data != nullptr && _type == mtpc_stickerSetMultiCovered); split(); return *(MTPDstickerSetMultiCovered*)data; } const MTPDstickerSetMultiCovered &c_stickerSetMultiCovered() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_stickerSetMultiCovered) throw mtpErrorWrongTypeId(_type, mtpc_stickerSetMultiCovered); + t_assert(data != nullptr && _type == mtpc_stickerSetMultiCovered); return *(const MTPDstickerSetMultiCovered*)data; } @@ -9894,12 +9356,12 @@ public: } MTPDmaskCoords &_maskCoords() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmaskCoords*)data; } const MTPDmaskCoords &c_maskCoords() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmaskCoords*)data; } @@ -9926,26 +9388,22 @@ public: } MTPDinputStickeredMediaPhoto &_inputStickeredMediaPhoto() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickeredMediaPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputStickeredMediaPhoto); + t_assert(data != nullptr && _type == mtpc_inputStickeredMediaPhoto); split(); return *(MTPDinputStickeredMediaPhoto*)data; } const MTPDinputStickeredMediaPhoto &c_inputStickeredMediaPhoto() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickeredMediaPhoto) throw mtpErrorWrongTypeId(_type, mtpc_inputStickeredMediaPhoto); + t_assert(data != nullptr && _type == mtpc_inputStickeredMediaPhoto); return *(const MTPDinputStickeredMediaPhoto*)data; } MTPDinputStickeredMediaDocument &_inputStickeredMediaDocument() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickeredMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputStickeredMediaDocument); + t_assert(data != nullptr && _type == mtpc_inputStickeredMediaDocument); split(); return *(MTPDinputStickeredMediaDocument*)data; } const MTPDinputStickeredMediaDocument &c_inputStickeredMediaDocument() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputStickeredMediaDocument) throw mtpErrorWrongTypeId(_type, mtpc_inputStickeredMediaDocument); + t_assert(data != nullptr && _type == mtpc_inputStickeredMediaDocument); return *(const MTPDinputStickeredMediaDocument*)data; } @@ -9975,12 +9433,12 @@ public: } MTPDgame &_game() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDgame*)data; } const MTPDgame &c_game() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDgame*)data; } @@ -10007,26 +9465,22 @@ public: } MTPDinputGameID &_inputGameID() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputGameID) throw mtpErrorWrongTypeId(_type, mtpc_inputGameID); + t_assert(data != nullptr && _type == mtpc_inputGameID); split(); return *(MTPDinputGameID*)data; } const MTPDinputGameID &c_inputGameID() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputGameID) throw mtpErrorWrongTypeId(_type, mtpc_inputGameID); + t_assert(data != nullptr && _type == mtpc_inputGameID); return *(const MTPDinputGameID*)data; } MTPDinputGameShortName &_inputGameShortName() { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputGameShortName) throw mtpErrorWrongTypeId(_type, mtpc_inputGameShortName); + t_assert(data != nullptr && _type == mtpc_inputGameShortName); split(); return *(MTPDinputGameShortName*)data; } const MTPDinputGameShortName &c_inputGameShortName() const { - if (!data) throw mtpErrorUninitialized(); - if (_type != mtpc_inputGameShortName) throw mtpErrorWrongTypeId(_type, mtpc_inputGameShortName); + t_assert(data != nullptr && _type == mtpc_inputGameShortName); return *(const MTPDinputGameShortName*)data; } @@ -10056,12 +9510,12 @@ public: } MTPDhighScore &_highScore() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDhighScore*)data; } const MTPDhighScore &c_highScore() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDhighScore*)data; } @@ -10087,12 +9541,12 @@ public: } MTPDmessages_highScores &_messages_highScores() { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); split(); return *(MTPDmessages_highScores*)data; } const MTPDmessages_highScores &c_messages_highScores() const { - if (!data) throw mtpErrorUninitialized(); + t_assert(data != nullptr); return *(const MTPDmessages_highScores*)data; } @@ -25416,7 +24870,7 @@ inline uint32 MTPserver_DH_Params::innerLength() const { return 0; } inline mtpTypeId MTPserver_DH_Params::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPserver_DH_Params::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -25561,7 +25015,7 @@ inline uint32 MTPset_client_DH_params_answer::innerLength() const { return 0; } inline mtpTypeId MTPset_client_DH_params_answer::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPset_client_DH_params_answer::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -25678,7 +25132,7 @@ inline uint32 MTPbadMsgNotification::innerLength() const { return 0; } inline mtpTypeId MTPbadMsgNotification::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPbadMsgNotification::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -25836,7 +25290,7 @@ inline uint32 MTPmsgDetailedInfo::innerLength() const { return 0; } inline mtpTypeId MTPmsgDetailedInfo::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmsgDetailedInfo::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -25961,7 +25415,7 @@ inline uint32 MTPrpcDropAnswer::innerLength() const { return 0; } inline mtpTypeId MTPrpcDropAnswer::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPrpcDropAnswer::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26114,7 +25568,7 @@ inline uint32 MTPdestroySessionRes::innerLength() const { return 0; } inline mtpTypeId MTPdestroySessionRes::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPdestroySessionRes::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26229,7 +25683,7 @@ inline uint32 MTPbool::innerLength() const { return 0; } inline mtpTypeId MTPbool::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPbool::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26330,7 +25784,7 @@ inline uint32 MTPinputPeer::innerLength() const { return 0; } inline mtpTypeId MTPinputPeer::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputPeer::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26418,7 +25872,7 @@ inline uint32 MTPinputUser::innerLength() const { return 0; } inline mtpTypeId MTPinputUser::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputUser::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26511,7 +25965,7 @@ inline uint32 MTPinputFile::innerLength() const { return 0; } inline mtpTypeId MTPinputFile::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputFile::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26624,7 +26078,7 @@ inline uint32 MTPinputMedia::innerLength() const { return 0; } inline mtpTypeId MTPinputMedia::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputMedia::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26895,7 +26349,7 @@ inline uint32 MTPinputChatPhoto::innerLength() const { return 0; } inline mtpTypeId MTPinputChatPhoto::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputChatPhoto::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -26959,7 +26413,7 @@ inline uint32 MTPinputGeoPoint::innerLength() const { return 0; } inline mtpTypeId MTPinputGeoPoint::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputGeoPoint::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27010,7 +26464,7 @@ inline uint32 MTPinputPhoto::innerLength() const { return 0; } inline mtpTypeId MTPinputPhoto::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputPhoto::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27069,7 +26523,7 @@ inline uint32 MTPinputFileLocation::innerLength() const { return 0; } inline mtpTypeId MTPinputFileLocation::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputFileLocation::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27194,7 +26648,7 @@ inline uint32 MTPpeer::innerLength() const { return 0; } inline mtpTypeId MTPpeer::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPpeer::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27262,7 +26716,7 @@ inline uint32 MTPstorage_fileType::innerLength() const { return 0; } inline mtpTypeId MTPstorage_fileType::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPstorage_fileType::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27342,7 +26796,7 @@ inline uint32 MTPfileLocation::innerLength() const { return 0; } inline mtpTypeId MTPfileLocation::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPfileLocation::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27415,7 +26869,7 @@ inline uint32 MTPuser::innerLength() const { return 0; } inline mtpTypeId MTPuser::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPuser::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27497,7 +26951,7 @@ inline uint32 MTPuserProfilePhoto::innerLength() const { return 0; } inline mtpTypeId MTPuserProfilePhoto::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPuserProfilePhoto::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27554,7 +27008,7 @@ inline uint32 MTPuserStatus::innerLength() const { return 0; } inline mtpTypeId MTPuserStatus::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPuserStatus::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27649,7 +27103,7 @@ inline uint32 MTPchat::innerLength() const { return 0; } inline mtpTypeId MTPchat::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchat::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27798,7 +27252,7 @@ inline uint32 MTPchatFull::innerLength() const { return 0; } inline mtpTypeId MTPchatFull::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchatFull::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27906,7 +27360,7 @@ inline uint32 MTPchatParticipant::innerLength() const { return 0; } inline mtpTypeId MTPchatParticipant::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchatParticipant::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -27992,7 +27446,7 @@ inline uint32 MTPchatParticipants::innerLength() const { return 0; } inline mtpTypeId MTPchatParticipants::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchatParticipants::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28060,7 +27514,7 @@ inline uint32 MTPchatPhoto::innerLength() const { return 0; } inline mtpTypeId MTPchatPhoto::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchatPhoto::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28119,7 +27573,7 @@ inline uint32 MTPmessage::innerLength() const { return 0; } inline mtpTypeId MTPmessage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28257,7 +27711,7 @@ inline uint32 MTPmessageMedia::innerLength() const { return 0; } inline mtpTypeId MTPmessageMedia::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessageMedia::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28455,7 +27909,7 @@ inline uint32 MTPmessageAction::innerLength() const { return 0; } inline mtpTypeId MTPmessageAction::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessageAction::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28708,7 +28162,7 @@ inline uint32 MTPphoto::innerLength() const { return 0; } inline mtpTypeId MTPphoto::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPphoto::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28784,7 +28238,7 @@ inline uint32 MTPphotoSize::innerLength() const { return 0; } inline mtpTypeId MTPphotoSize::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPphotoSize::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -28874,7 +28328,7 @@ inline uint32 MTPgeoPoint::innerLength() const { return 0; } inline mtpTypeId MTPgeoPoint::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPgeoPoint::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29049,7 +28503,7 @@ inline uint32 MTPinputNotifyPeer::innerLength() const { return 0; } inline mtpTypeId MTPinputNotifyPeer::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputNotifyPeer::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29102,7 +28556,7 @@ inline uint32 MTPinputPeerNotifyEvents::innerLength() const { return 0; } inline mtpTypeId MTPinputPeerNotifyEvents::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputPeerNotifyEvents::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29164,7 +28618,7 @@ inline uint32 MTPpeerNotifyEvents::innerLength() const { return 0; } inline mtpTypeId MTPpeerNotifyEvents::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPpeerNotifyEvents::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29200,7 +28654,7 @@ inline uint32 MTPpeerNotifySettings::innerLength() const { return 0; } inline mtpTypeId MTPpeerNotifySettings::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPpeerNotifySettings::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29286,7 +28740,7 @@ inline uint32 MTPwallPaper::innerLength() const { return 0; } inline mtpTypeId MTPwallPaper::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPwallPaper::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29357,7 +28811,7 @@ inline uint32 MTPreportReason::innerLength() const { return 0; } inline mtpTypeId MTPreportReason::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPreportReason::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29603,7 +29057,7 @@ inline uint32 MTPcontacts_contacts::innerLength() const { return 0; } inline mtpTypeId MTPcontacts_contacts::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPcontacts_contacts::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29689,7 +29143,7 @@ inline uint32 MTPcontacts_blocked::innerLength() const { return 0; } inline mtpTypeId MTPcontacts_blocked::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPcontacts_blocked::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29758,7 +29212,7 @@ inline uint32 MTPmessages_dialogs::innerLength() const { return 0; } inline mtpTypeId MTPmessages_dialogs::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_dialogs::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -29839,7 +29293,7 @@ inline uint32 MTPmessages_messages::innerLength() const { return 0; } inline mtpTypeId MTPmessages_messages::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_messages::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -30016,7 +29470,7 @@ inline uint32 MTPmessagesFilter::innerLength() const { return 0; } inline mtpTypeId MTPmessagesFilter::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessagesFilter::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -30281,7 +29735,7 @@ inline uint32 MTPupdate::innerLength() const { return 0; } inline mtpTypeId MTPupdate::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPupdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -31282,7 +30736,7 @@ inline uint32 MTPupdates_difference::innerLength() const { return 0; } inline mtpTypeId MTPupdates_difference::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPupdates_difference::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -31398,7 +30852,7 @@ inline uint32 MTPupdates::innerLength() const { return 0; } inline mtpTypeId MTPupdates::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPupdates::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -31603,7 +31057,7 @@ inline uint32 MTPphotos_photos::innerLength() const { return 0; } inline mtpTypeId MTPphotos_photos::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPphotos_photos::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -31867,7 +31321,7 @@ inline uint32 MTPhelp_appUpdate::innerLength() const { return 0; } inline mtpTypeId MTPhelp_appUpdate::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPhelp_appUpdate::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -31965,7 +31419,7 @@ inline uint32 MTPencryptedChat::innerLength() const { return 0; } inline mtpTypeId MTPencryptedChat::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPencryptedChat::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32128,7 +31582,7 @@ inline uint32 MTPencryptedFile::innerLength() const { return 0; } inline mtpTypeId MTPencryptedFile::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPencryptedFile::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32193,7 +31647,7 @@ inline uint32 MTPinputEncryptedFile::innerLength() const { return 0; } inline mtpTypeId MTPinputEncryptedFile::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputEncryptedFile::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32288,7 +31742,7 @@ inline uint32 MTPencryptedMessage::innerLength() const { return 0; } inline mtpTypeId MTPencryptedMessage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPencryptedMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32365,7 +31819,7 @@ inline uint32 MTPmessages_dhConfig::innerLength() const { return 0; } inline mtpTypeId MTPmessages_dhConfig::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_dhConfig::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32434,7 +31888,7 @@ inline uint32 MTPmessages_sentEncryptedMessage::innerLength() const { return 0; } inline mtpTypeId MTPmessages_sentEncryptedMessage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_sentEncryptedMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32495,7 +31949,7 @@ inline uint32 MTPinputDocument::innerLength() const { return 0; } inline mtpTypeId MTPinputDocument::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputDocument::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32550,7 +32004,7 @@ inline uint32 MTPdocument::innerLength() const { return 0; } inline mtpTypeId MTPdocument::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPdocument::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32654,7 +32108,7 @@ inline uint32 MTPnotifyPeer::innerLength() const { return 0; } inline mtpTypeId MTPnotifyPeer::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPnotifyPeer::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32725,7 +32179,7 @@ inline uint32 MTPsendMessageAction::innerLength() const { return 0; } inline mtpTypeId MTPsendMessageAction::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPsendMessageAction::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32879,7 +32333,7 @@ inline uint32 MTPinputPrivacyKey::innerLength() const { return 0; } inline mtpTypeId MTPinputPrivacyKey::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputPrivacyKey::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32909,7 +32363,7 @@ inline uint32 MTPprivacyKey::innerLength() const { return 0; } inline mtpTypeId MTPprivacyKey::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPprivacyKey::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -32949,7 +32403,7 @@ inline uint32 MTPinputPrivacyRule::innerLength() const { return 0; } inline mtpTypeId MTPinputPrivacyRule::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputPrivacyRule::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33032,7 +32486,7 @@ inline uint32 MTPprivacyRule::innerLength() const { return 0; } inline mtpTypeId MTPprivacyRule::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPprivacyRule::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33183,7 +32637,7 @@ inline uint32 MTPdocumentAttribute::innerLength() const { return 0; } inline mtpTypeId MTPdocumentAttribute::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPdocumentAttribute::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33319,7 +32773,7 @@ inline uint32 MTPmessages_stickers::innerLength() const { return 0; } inline mtpTypeId MTPmessages_stickers::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_stickers::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33399,7 +32853,7 @@ inline uint32 MTPmessages_allStickers::innerLength() const { return 0; } inline mtpTypeId MTPmessages_allStickers::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_allStickers::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33502,7 +32956,7 @@ inline uint32 MTPcontactLink::innerLength() const { return 0; } inline mtpTypeId MTPcontactLink::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPcontactLink::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33556,7 +33010,7 @@ inline uint32 MTPwebPage::innerLength() const { return 0; } inline mtpTypeId MTPwebPage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPwebPage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33745,7 +33199,7 @@ inline uint32 MTPaccount_password::innerLength() const { return 0; } inline mtpTypeId MTPaccount_password::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPaccount_password::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33933,7 +33387,7 @@ inline uint32 MTPexportedChatInvite::innerLength() const { return 0; } inline mtpTypeId MTPexportedChatInvite::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPexportedChatInvite::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -33986,7 +33440,7 @@ inline uint32 MTPchatInvite::innerLength() const { return 0; } inline mtpTypeId MTPchatInvite::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchatInvite::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -34058,7 +33512,7 @@ inline uint32 MTPinputStickerSet::innerLength() const { return 0; } inline mtpTypeId MTPinputStickerSet::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputStickerSet::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -34279,7 +33733,7 @@ inline uint32 MTPkeyboardButton::innerLength() const { return 0; } inline mtpTypeId MTPkeyboardButton::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPkeyboardButton::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -34461,7 +33915,7 @@ inline uint32 MTPreplyMarkup::innerLength() const { return 0; } inline mtpTypeId MTPreplyMarkup::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPreplyMarkup::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -34555,7 +34009,7 @@ inline uint32 MTPhelp_appChangelog::innerLength() const { return 0; } inline mtpTypeId MTPhelp_appChangelog::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPhelp_appChangelog::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -34652,7 +34106,7 @@ inline uint32 MTPmessageEntity::innerLength() const { return 0; } inline mtpTypeId MTPmessageEntity::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessageEntity::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -34910,7 +34364,7 @@ inline uint32 MTPinputChannel::innerLength() const { return 0; } inline mtpTypeId MTPinputChannel::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputChannel::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35029,7 +34483,7 @@ inline uint32 MTPupdates_channelDifference::innerLength() const { return 0; } inline mtpTypeId MTPupdates_channelDifference::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPupdates_channelDifference::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35140,7 +34594,7 @@ inline uint32 MTPchannelMessagesFilter::innerLength() const { return 0; } inline mtpTypeId MTPchannelMessagesFilter::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchannelMessagesFilter::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35212,7 +34666,7 @@ inline uint32 MTPchannelParticipant::innerLength() const { return 0; } inline mtpTypeId MTPchannelParticipant::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchannelParticipant::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35343,7 +34797,7 @@ inline uint32 MTPchannelParticipantsFilter::innerLength() const { return 0; } inline mtpTypeId MTPchannelParticipantsFilter::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchannelParticipantsFilter::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35383,7 +34837,7 @@ inline uint32 MTPchannelParticipantRole::innerLength() const { return 0; } inline mtpTypeId MTPchannelParticipantRole::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPchannelParticipantRole::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35515,7 +34969,7 @@ inline uint32 MTPfoundGif::innerLength() const { return 0; } inline mtpTypeId MTPfoundGif::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPfoundGif::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35617,7 +35071,7 @@ inline uint32 MTPmessages_savedGifs::innerLength() const { return 0; } inline mtpTypeId MTPmessages_savedGifs::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_savedGifs::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35688,7 +35142,7 @@ inline uint32 MTPinputBotInlineMessage::innerLength() const { return 0; } inline mtpTypeId MTPinputBotInlineMessage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputBotInlineMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -35861,7 +35315,7 @@ inline uint32 MTPinputBotInlineResult::innerLength() const { return 0; } inline mtpTypeId MTPinputBotInlineResult::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputBotInlineResult::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36014,7 +35468,7 @@ inline uint32 MTPbotInlineMessage::innerLength() const { return 0; } inline mtpTypeId MTPbotInlineMessage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPbotInlineMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36161,7 +35615,7 @@ inline uint32 MTPbotInlineResult::innerLength() const { return 0; } inline mtpTypeId MTPbotInlineResult::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPbotInlineResult::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36353,7 +35807,7 @@ inline uint32 MTPauth_codeType::innerLength() const { return 0; } inline mtpTypeId MTPauth_codeType::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPauth_codeType::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36406,7 +35860,7 @@ inline uint32 MTPauth_sentCodeType::innerLength() const { return 0; } inline mtpTypeId MTPauth_sentCodeType::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPauth_sentCodeType::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36673,7 +36127,7 @@ inline uint32 MTPtopPeerCategory::innerLength() const { return 0; } inline mtpTypeId MTPtopPeerCategory::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPtopPeerCategory::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36755,7 +36209,7 @@ inline uint32 MTPcontacts_topPeers::innerLength() const { return 0; } inline mtpTypeId MTPcontacts_topPeers::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPcontacts_topPeers::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36808,7 +36262,7 @@ inline uint32 MTPdraftMessage::innerLength() const { return 0; } inline mtpTypeId MTPdraftMessage::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPdraftMessage::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36866,7 +36320,7 @@ inline uint32 MTPmessages_featuredStickers::innerLength() const { return 0; } inline mtpTypeId MTPmessages_featuredStickers::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_featuredStickers::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36919,7 +36373,7 @@ inline uint32 MTPmessages_recentStickers::innerLength() const { return 0; } inline mtpTypeId MTPmessages_recentStickers::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_recentStickers::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -36999,7 +36453,7 @@ inline uint32 MTPmessages_stickerSetInstallResult::innerLength() const { return 0; } inline mtpTypeId MTPmessages_stickerSetInstallResult::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPmessages_stickerSetInstallResult::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -37052,7 +36506,7 @@ inline uint32 MTPstickerSetCovered::innerLength() const { return 0; } inline mtpTypeId MTPstickerSetCovered::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPstickerSetCovered::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -37152,7 +36606,7 @@ inline uint32 MTPinputStickeredMedia::innerLength() const { return 0; } inline mtpTypeId MTPinputStickeredMedia::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputStickeredMedia::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { @@ -37257,7 +36711,7 @@ inline uint32 MTPinputGame::innerLength() const { return 0; } inline mtpTypeId MTPinputGame::type() const { - if (!_type) throw mtpErrorUninitialized(); + t_assert(_type != 0); return _type; } inline void MTPinputGame::read(const mtpPrime *&from, const mtpPrime *end, mtpTypeId cons) { diff --git a/Telegram/SourceFiles/mtproto/session.h b/Telegram/SourceFiles/mtproto/session.h index f46694e3a2..4c8b17c693 100644 --- a/Telegram/SourceFiles/mtproto/session.h +++ b/Telegram/SourceFiles/mtproto/session.h @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mtproto/connection.h" #include "mtproto/dcenter.h" #include "mtproto/rpc_sender.h" +#include "core/single_timer.h" namespace MTP { namespace internal { @@ -31,7 +32,6 @@ class Session; class SessionData { public: - SessionData(Session *creator) : _session(0) , _salt(0) @@ -227,7 +227,6 @@ class Session : public QObject { Q_OBJECT public: - Session(int32 dcenter); void restart(); @@ -237,7 +236,6 @@ public: void unpaused(); int32 getDcWithShift() const; - ~Session(); QReadWriteLock *keyMutex() const; void notifyKeyCreated(const AuthKeyPtr &key); @@ -255,15 +253,15 @@ public: void sendPrepared(const mtpRequest &request, uint64 msCanWait = 0, bool newRequest = true); // nulls msgId and seqNo in request, if newRequest = true -signals: + ~Session(); +signals: void authKeyCreated(); void needToSend(); void needToPing(); void needToRestart(); public slots: - void needToResumeAndSend(); mtpRequestId resend(quint64 msgId, quint64 msCanWait = 0, bool forceContainer = false, bool sendMsgStateInfo = false); @@ -283,7 +281,6 @@ public slots: void sendMsgsStateInfo(quint64 msgId, QByteArray data); private: - Connection *_connection; bool _killed; diff --git a/Telegram/SourceFiles/observer_peer.cpp b/Telegram/SourceFiles/observer_peer.cpp index e4d463e5f4..66dfb36020 100644 --- a/Telegram/SourceFiles/observer_peer.cpp +++ b/Telegram/SourceFiles/observer_peer.cpp @@ -98,8 +98,8 @@ void peerUpdatedSendDelayed() { if (!SmallUpdates || !AllUpdates || SmallUpdates->empty()) return; - auto smallList = createAndSwap(*SmallUpdates); - auto allList = createAndSwap(*AllUpdates); + auto smallList = base::take(*SmallUpdates); + auto allList = base::take(*AllUpdates); for (auto &update : smallList) { PeerUpdated().notify(std_::move(update), true); } diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index ce9e2b1c06..fe87679cd7 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -106,7 +106,7 @@ void RadialProgressItem::checkRadialFinished() { } RadialProgressItem::~RadialProgressItem() { - deleteAndMark(_radial); + delete base::take(_radial); } void FileBase::setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const { diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index 7a2c2b130e..631a51ae30 100644 --- a/Telegram/SourceFiles/overviewwidget.h +++ b/Telegram/SourceFiles/overviewwidget.h @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "window/section_widget.h" +#include "ui/popupmenu.h" namespace Overview { namespace Layout { diff --git a/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp new file mode 100644 index 0000000000..23ba37b4e1 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp @@ -0,0 +1,122 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "platform/linux/linux_libnotify.h" + +#include "platform/linux/linux_libs.h" + +namespace Platform { +namespace Libs { +namespace { + +bool loadLibrary(QLibrary &lib, const char *name, int version) { + DEBUG_LOG(("Loading '%1' with version %2...").arg(QLatin1String(name)).arg(version)); + lib.setFileNameAndVersion(QLatin1String(name), version); + if (lib.load()) { + DEBUG_LOG(("Loaded '%1' with version %2!").arg(QLatin1String(name)).arg(version)); + return true; + } + lib.setFileNameAndVersion(QLatin1String(name), QString()); + if (lib.load()) { + DEBUG_LOG(("Loaded '%1' without version!").arg(QLatin1String(name))); + return true; + } + LOG(("Could not load '%1' with version %2 :(").arg(QLatin1String(name)).arg(version)); + return false; +} + +} // namespace + +f_notify_init notify_init = nullptr; +f_notify_uninit notify_uninit = nullptr; +f_notify_is_initted notify_is_initted = nullptr; +//f_notify_get_app_name notify_get_app_name = nullptr; +//f_notify_set_app_name notify_set_app_name = nullptr; +f_notify_get_server_caps notify_get_server_caps = nullptr; +f_notify_get_server_info notify_get_server_info = nullptr; + +f_notify_notification_new notify_notification_new = nullptr; +//f_notify_notification_update notify_notification_update = nullptr; +f_notify_notification_show notify_notification_show = nullptr; +//f_notify_notification_set_app_name notify_notification_set_app_name = nullptr; +f_notify_notification_set_timeout notify_notification_set_timeout = nullptr; +//f_notify_notification_set_category notify_notification_set_category = nullptr; +//f_notify_notification_set_urgency notify_notification_set_urgency = nullptr; +//f_notify_notification_set_icon_from_pixbuf notify_notification_set_icon_from_pixbuf = nullptr; +f_notify_notification_set_image_from_pixbuf notify_notification_set_image_from_pixbuf = nullptr; +//f_notify_notification_set_hint notify_notification_set_hint = nullptr; +//f_notify_notification_set_hint_int32 notify_notification_set_hint_int32 = nullptr; +//f_notify_notification_set_hint_uint32 notify_notification_set_hint_uint32 = nullptr; +//f_notify_notification_set_hint_double notify_notification_set_hint_double = nullptr; +f_notify_notification_set_hint_string notify_notification_set_hint_string = nullptr; +//f_notify_notification_set_hint_byte notify_notification_set_hint_byte = nullptr; +//f_notify_notification_set_hint_byte_array notify_notification_set_hint_byte_array = nullptr; +//f_notify_notification_clear_hints notify_notification_clear_hints = nullptr; +f_notify_notification_add_action notify_notification_add_action = nullptr; +f_notify_notification_clear_actions notify_notification_clear_actions = nullptr; +f_notify_notification_close notify_notification_close = nullptr; +f_notify_notification_get_closed_reason notify_notification_get_closed_reason = nullptr; + +void startLibNotify() { + DEBUG_LOG(("Loading libnotify")); + + QLibrary lib_notify; + if (!loadLibrary(lib_notify, "notify", 4)) { + if (!loadLibrary(lib_notify, "notify", 5)) { + if (!loadLibrary(lib_notify, "notify", 1)) { + return; + } + } + } + + load(lib_notify, "notify_init", notify_init); + load(lib_notify, "notify_uninit", notify_uninit); + load(lib_notify, "notify_is_initted", notify_is_initted); +// load(lib_notify, "notify_get_app_name", notify_get_app_name); +// load(lib_notify, "notify_set_app_name", notify_set_app_name); + load(lib_notify, "notify_get_server_caps", notify_get_server_caps); + load(lib_notify, "notify_get_server_info", notify_get_server_info); + + load(lib_notify, "notify_notification_new", notify_notification_new); +// load(lib_notify, "notify_notification_update", notify_notification_update); + load(lib_notify, "notify_notification_show", notify_notification_show); +// load(lib_notify, "notify_notification_set_app_name", notify_notification_set_app_name); + load(lib_notify, "notify_notification_set_timeout", notify_notification_set_timeout); +// load(lib_notify, "notify_notification_set_category", notify_notification_set_category); +// load(lib_notify, "notify_notification_set_urgency", notify_notification_set_urgency); +// load(lib_notify, "notify_notification_set_icon_from_pixbuf", notify_notification_set_icon_from_pixbuf); + load(lib_notify, "notify_notification_set_image_from_pixbuf", notify_notification_set_image_from_pixbuf); +// load(lib_notify, "notify_notification_set_hint", notify_notification_set_hint); +// load(lib_notify, "notify_notification_set_hint_int32", notify_notification_set_hint_int32); +// load(lib_notify, "notify_notification_set_hint_uint32", notify_notification_set_hint_uint32); +// load(lib_notify, "notify_notification_set_hint_double", notify_notification_set_hint_double); + load(lib_notify, "notify_notification_set_hint_string", notify_notification_set_hint_string); +// load(lib_notify, "notify_notification_set_hint_byte", notify_notification_set_hint_byte); +// load(lib_notify, "notify_notification_set_hint_byte_array", notify_notification_set_hint_byte_array); +// load(lib_notify, "notify_notification_clear_hints", notify_notification_clear_hints); + load(lib_notify, "notify_notification_add_action", notify_notification_add_action); + load(lib_notify, "notify_notification_clear_actions", notify_notification_clear_actions); + load(lib_notify, "notify_notification_close", notify_notification_close); + load(lib_notify, "notify_notification_get_closed_reason", notify_notification_get_closed_reason); +} + +} // namespace Libs +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/linux_libnotify.h b/Telegram/SourceFiles/platform/linux/linux_libnotify.h new file mode 100644 index 0000000000..9cde80d7c6 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_libnotify.h @@ -0,0 +1,131 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +extern "C" { +#undef signals +#include +#define signals public +} // extern "C" + +namespace Platform { +namespace Libs { + +void startLibNotify(); + +constexpr gint NOTIFY_EXPIRES_DEFAULT = -1; +constexpr gint NOTIFY_EXPIRES_NEVER = 0; + +struct NotifyNotification; +typedef enum { + NOTIFY_URGENCY_LOW, + NOTIFY_URGENCY_NORMAL, + NOTIFY_URGENCY_CRITICAL, +} NotifyUrgency; + +using NotifyActionCallback = void (*)(NotifyNotification *notification, char *action, gpointer user_data); + +using f_notify_init = gboolean (*)(const char *app_name); +extern f_notify_init notify_init; + +using f_notify_uninit = void (*)(void); +extern f_notify_uninit notify_uninit; + +using f_notify_is_initted = gboolean (*)(void); +extern f_notify_is_initted notify_is_initted; + +//using f_notify_get_app_name = const char* (*)(void); +//extern f_notify_get_app_name notify_get_app_name; + +//using f_notify_set_app_name = void (*)(const char *app_name); +//extern f_notify_set_app_name notify_set_app_name; + +using f_notify_get_server_caps = GList* (*)(void); +extern f_notify_get_server_caps notify_get_server_caps; + +using f_notify_get_server_info = gboolean (*)(char **ret_name, char **ret_vendor, char **ret_version, char **ret_spec_version); +extern f_notify_get_server_info notify_get_server_info; + +using f_notify_notification_new = NotifyNotification* (*)(const char *summary, const char *body, const char *icon); +extern f_notify_notification_new notify_notification_new; + +//using f_notify_notification_update = gboolean (*)(NotifyNotification *notification, const char *summary, const char *body, const char *icon); +//extern f_notify_notification_update notify_notification_update; + +using f_notify_notification_show = gboolean (*)(NotifyNotification *notification, GError **error); +extern f_notify_notification_show notify_notification_show; + +//using f_notify_notification_set_app_name = void (*)(NotifyNotification *notification, const char *app_name); +//extern f_notify_notification_set_app_name notify_notification_set_app_name; + +using f_notify_notification_set_timeout = void (*)(NotifyNotification *notification, gint timeout); +extern f_notify_notification_set_timeout notify_notification_set_timeout; + +//using f_notify_notification_set_category = void (*)(NotifyNotification *notification, const char *category); +//extern f_notify_notification_set_category notify_notification_set_category; + +//using f_notify_notification_set_urgency = void (*)(NotifyNotification *notification, NotifyUrgency urgency); +//extern f_notify_notification_set_urgency notify_notification_set_urgency; + +//using f_notify_notification_set_icon_from_pixbuf = void (*)(NotifyNotification *notification, GdkPixbuf *icon); +//extern f_notify_notification_set_icon_from_pixbuf notify_notification_set_icon_from_pixbuf; + +using f_notify_notification_set_image_from_pixbuf = void (*)(NotifyNotification *notification, GdkPixbuf *pixbuf); +extern f_notify_notification_set_image_from_pixbuf notify_notification_set_image_from_pixbuf; + +//using f_notify_notification_set_hint = void (*)(NotifyNotification *notification, const char *key, GVariant *value); +//extern f_notify_notification_set_hint notify_notification_set_hint; + +//using f_notify_notification_set_hint_int32 = void (*)(NotifyNotification *notification, const char *key, gint value); +//extern f_notify_notification_set_hint_int32 notify_notification_set_hint_int32; + +//using f_notify_notification_set_hint_uint32 = void (*)(NotifyNotification *notification, const char *key, guint value); +//extern f_notify_notification_set_hint_uint32 notify_notification_set_hint_uint32; + +//using f_notify_notification_set_hint_double = void (*)(NotifyNotification *notification, const char *key, gdouble value); +//extern f_notify_notification_set_hint_double notify_notification_set_hint_double; + +using f_notify_notification_set_hint_string = void (*)(NotifyNotification *notification, const char *key, const char *value); +extern f_notify_notification_set_hint_string notify_notification_set_hint_string; + +//using f_notify_notification_set_hint_byte = void (*)(NotifyNotification *notification, const char *key, guchar value); +//extern f_notify_notification_set_hint_byte notify_notification_set_hint_byte; + +//using f_notify_notification_set_hint_byte_array = void (*)(NotifyNotification *notification, const char *key, const guchar *value, gsize len); +//extern f_notify_notification_set_hint_byte_array notify_notification_set_hint_byte_array; + +//using f_notify_notification_clear_hints = void (*)(NotifyNotification *notification); +//extern f_notify_notification_clear_hints notify_notification_clear_hints; + +using f_notify_notification_add_action = void (*)(NotifyNotification *notification, const char *action, const char *label, NotifyActionCallback callback, gpointer user_data, GFreeFunc free_func); +extern f_notify_notification_add_action notify_notification_add_action; + +using f_notify_notification_clear_actions = void (*)(NotifyNotification *notification); +extern f_notify_notification_clear_actions notify_notification_clear_actions; + +using f_notify_notification_close = gboolean (*)(NotifyNotification *notification, GError **error); +extern f_notify_notification_close notify_notification_close; + +using f_notify_notification_get_closed_reason = gint (*)(const NotifyNotification *notification); +extern f_notify_notification_get_closed_reason notify_notification_get_closed_reason; + +} // namespace Libs +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.cpp b/Telegram/SourceFiles/platform/linux/linux_libs.cpp index 484b6c534d..110180a4c2 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libs.cpp @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "platform/linux/linux_libs.h" #include "platform/linux/linux_gdk_helper.h" +#include "platform/linux/linux_libnotify.h" namespace Platform { namespace Libs { @@ -92,10 +93,16 @@ bool setupGtkBase(QLibrary &lib_gtk) { if (!load(lib_gtk, "g_type_check_instance_cast", g_type_check_instance_cast)) return false; if (!load(lib_gtk, "g_type_check_instance_is_a", g_type_check_instance_is_a)) return false; if (!load(lib_gtk, "g_signal_connect_data", g_signal_connect_data)) return false; + if (!load(lib_gtk, "g_signal_handler_disconnect", g_signal_handler_disconnect)) return false; if (!load(lib_gtk, "g_object_ref_sink", g_object_ref_sink)) return false; if (!load(lib_gtk, "g_object_unref", g_object_unref)) return false; if (!load(lib_gtk, "g_free", g_free)) return false; + if (!load(lib_gtk, "g_list_foreach", g_list_foreach)) return false; + if (!load(lib_gtk, "g_list_free", g_list_free)) return false; + if (!load(lib_gtk, "g_list_free_full", g_list_free_full)) return false; + + if (!load(lib_gtk, "g_error_free", g_error_free)) return false; if (!load(lib_gtk, "g_slist_free", g_slist_free)) return false; DEBUG_LOG(("Library gtk functions loaded!")); @@ -169,12 +176,14 @@ f_gtk_dialog_run gtk_dialog_run = nullptr; f_g_type_check_instance_cast g_type_check_instance_cast = nullptr; f_g_type_check_instance_is_a g_type_check_instance_is_a = nullptr; f_g_signal_connect_data g_signal_connect_data = nullptr; +f_g_signal_handler_disconnect g_signal_handler_disconnect = nullptr; f_app_indicator_new app_indicator_new = nullptr; f_app_indicator_set_status app_indicator_set_status = nullptr; f_app_indicator_set_menu app_indicator_set_menu = nullptr; f_app_indicator_set_icon_full app_indicator_set_icon_full = nullptr; f_gdk_init_check gdk_init_check = nullptr; f_gdk_pixbuf_new_from_data gdk_pixbuf_new_from_data = nullptr; +f_gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file = nullptr; f_gtk_status_icon_new_from_pixbuf gtk_status_icon_new_from_pixbuf = nullptr; f_gtk_status_icon_set_from_pixbuf gtk_status_icon_set_from_pixbuf = nullptr; f_gtk_status_icon_new_from_file gtk_status_icon_new_from_file = nullptr; @@ -191,6 +200,10 @@ f_g_object_ref_sink g_object_ref_sink = nullptr; f_g_object_unref g_object_unref = nullptr; f_g_idle_add g_idle_add = nullptr; f_g_free g_free = nullptr; +f_g_list_foreach g_list_foreach = nullptr; +f_g_list_free g_list_free = nullptr; +f_g_list_free_full g_list_free_full = nullptr; +f_g_error_free g_error_free = nullptr; f_g_slist_free g_slist_free = nullptr; #ifndef TDESKTOP_DISABLE_UNITY_INTEGRATION f_unity_launcher_entry_set_count unity_launcher_entry_set_count = nullptr; @@ -233,6 +246,7 @@ void start() { if (gtkLoaded) { load(lib_gtk, "gdk_init_check", gdk_init_check); load(lib_gtk, "gdk_pixbuf_new_from_data", gdk_pixbuf_new_from_data); + load(lib_gtk, "gdk_pixbuf_new_from_file", gdk_pixbuf_new_from_file); load(lib_gtk, "gtk_status_icon_new_from_pixbuf", gtk_status_icon_new_from_pixbuf); load(lib_gtk, "gtk_status_icon_set_from_pixbuf", gtk_status_icon_set_from_pixbuf); load(lib_gtk, "gtk_status_icon_new_from_file", gtk_status_icon_new_from_file); @@ -266,6 +280,10 @@ void start() { load(lib_unity, "unity_launcher_entry_set_count_visible", unity_launcher_entry_set_count_visible); } #endif // TDESKTOP_DISABLE_UNITY_INTEGRATION + + if (gtkLoaded) { + startLibNotify(); + } } } // namespace Libs diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.h b/Telegram/SourceFiles/platform/linux/linux_libs.h index 6fd9a802f3..3b542a4070 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.h +++ b/Telegram/SourceFiles/platform/linux/linux_libs.h @@ -247,14 +247,17 @@ extern f_gtk_dialog_run gtk_dialog_run; typedef gulong (*f_g_signal_connect_data)(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags); extern f_g_signal_connect_data g_signal_connect_data; -inline gulong g_signal_connect_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) { - return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, (GConnectFlags)0); +inline gulong g_signal_connect_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data = nullptr) { + return g_signal_connect_data(instance, detailed_signal, c_handler, data, destroy_data, (GConnectFlags)0); } -inline gulong g_signal_connect_swapped_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data) { - return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, G_CONNECT_SWAPPED); +inline gulong g_signal_connect_swapped_helper(gpointer instance, const gchar *detailed_signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data = nullptr) { + return g_signal_connect_data(instance, detailed_signal, c_handler, data, destroy_data, G_CONNECT_SWAPPED); } +typedef void (*f_g_signal_handler_disconnect)(gpointer instance, gulong handler_id); +extern f_g_signal_handler_disconnect g_signal_handler_disconnect; + typedef AppIndicator* (*f_app_indicator_new)(const gchar *id, const gchar *icon_name, AppIndicatorCategory category); extern f_app_indicator_new app_indicator_new; @@ -273,6 +276,9 @@ extern f_gdk_init_check gdk_init_check; typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_data)(const guchar *data, GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, int width, int height, int rowstride, GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data); extern f_gdk_pixbuf_new_from_data gdk_pixbuf_new_from_data; +typedef GdkPixbuf* (*f_gdk_pixbuf_new_from_file)(const gchar *filename, GError **error); +extern f_gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file; + typedef GtkStatusIcon* (*f_gtk_status_icon_new_from_pixbuf)(GdkPixbuf *pixbuf); extern f_gtk_status_icon_new_from_pixbuf gtk_status_icon_new_from_pixbuf; @@ -321,6 +327,18 @@ extern f_g_idle_add g_idle_add; typedef void (*f_g_free)(gpointer mem); extern f_g_free g_free; +typedef void (*f_g_list_foreach)(GList *list, GFunc func, gpointer user_data); +extern f_g_list_foreach g_list_foreach; + +typedef void (*f_g_list_free)(GList *list); +extern f_g_list_free g_list_free; + +typedef void (*f_g_list_free_full)(GList *list, GDestroyNotify free_func); +extern f_g_list_free_full g_list_free_full; + +typedef void (*f_g_error_free)(GError *error); +extern f_g_error_free g_error_free; + typedef void (*f_g_slist_free)(GSList *list); extern f_g_slist_free g_slist_free; diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 2647ea36e6..42e4716eff 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -22,6 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "platform/linux/main_window_linux.h" #include "platform/linux/linux_libs.h" +#include "platform/platform_notifications_manager.h" #include "mainwindow.h" #include "application.h" #include "lang.h" @@ -63,22 +64,11 @@ gboolean _trayIconResized(GtkStatusIcon *status_icon, gint size, gpointer popup_ return FALSE; } -#if Q_BYTE_ORDER == Q_BIG_ENDIAN - -#define QT_RED 3 -#define QT_GREEN 2 -#define QT_BLUE 1 -#define QT_ALPHA 0 - -#else - #define QT_RED 0 #define QT_GREEN 1 #define QT_BLUE 2 #define QT_ALPHA 3 -#endif - #define GTK_RED 2 #define GTK_GREEN 1 #define GTK_BLUE 0 @@ -262,13 +252,19 @@ void MainWindow::psSetupTrayIcon() { trayIcon->setToolTip(str_const_toString(AppName)); connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(toggleTray(QSystemTrayIcon::ActivationReason)), Qt::UniqueConnection); + + // This is very important for native notifications via libnotify! + // Some notification servers compose several notifications with a "Reply" + // action into one and after that a click on "Reply" button does not call + // the specified callback from any of the sent notification - libnotify + // just ignores ibus messages, but Qt tray icon at least emits this signal. connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(showFromTray())); + App::wnd()->updateTrayMenu(); } psUpdateCounter(); trayIcon->show(); - psUpdateDelegate(); } } @@ -367,6 +363,10 @@ void MainWindow::psUpdateCounter() { } } +bool MainWindow::psHasNativeNotifications() { + return Notifications::supported(); +} + void MainWindow::LibsLoaded() { QString cdesktop = QString(getenv("XDG_CURRENT_DESKTOP")).toLower(); noQtTrayIcon = (cdesktop == qstr("pantheon")) || (cdesktop == qstr("gnome")); @@ -430,9 +430,6 @@ void MainWindow::LibsLoaded() { #endif // TDESKTOP_DISABLE_UNITY_INTEGRATION } -void MainWindow::psUpdateDelegate() { -} - void MainWindow::psInitSize() { setMinimumWidth(st::wndMinWidth); setMinimumHeight(st::wndMinHeight); @@ -663,18 +660,6 @@ void MainWindow::psUpdateMargins() { void MainWindow::psFlash() { } -void MainWindow::psActivateNotify(NotifyWindow *w) { -} - -void MainWindow::psClearNotifies(PeerId peerId) { -} - -void MainWindow::psNotifyShown(NotifyWindow *w) { -} - -void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { -} - MainWindow::~MainWindow() { if (_trayIcon) { Libs::g_object_unref(_trayIcon); diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index 2526a9c5fc..f5b2aa2e68 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -22,8 +22,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" -class NotifyWindow; - namespace Platform { class MainWindow : public Window::MainWindow { @@ -58,16 +56,9 @@ public: return posInited; } - void psActivateNotify(NotifyWindow *w); - void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(NotifyWindow *w); - void psPlatformNotify(HistoryItem *item, int32 fwdCount); - void psUpdateCounter(); - bool psHasNativeNotifications() { - return false; - } + bool psHasNativeNotifications(); virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; @@ -76,8 +67,6 @@ public: ~MainWindow(); public slots: - - void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psShowTrayMenu(); diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp new file mode 100644 index 0000000000..a15a76c364 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -0,0 +1,491 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "platform/linux/notifications_manager_linux.h" + +#include "window/notifications_utilities.h" +#include "platform/linux/linux_libnotify.h" +#include "platform/linux/linux_libs.h" +#include "lang.h" + +namespace Platform { +namespace Notifications { +namespace { + +NeverFreedPointer ManagerInstance; + +bool LibNotifyLoaded() { + return (Libs::notify_init != nullptr) + && (Libs::notify_uninit != nullptr) + && (Libs::notify_is_initted != nullptr) +// && (Libs::notify_get_app_name != nullptr) +// && (Libs::notify_set_app_name != nullptr) + && (Libs::notify_get_server_caps != nullptr) + && (Libs::notify_get_server_info != nullptr) + && (Libs::notify_notification_new != nullptr) +// && (Libs::notify_notification_update != nullptr) + && (Libs::notify_notification_show != nullptr) +// && (Libs::notify_notification_set_app_name != nullptr) + && (Libs::notify_notification_set_timeout != nullptr) +// && (Libs::notify_notification_set_category != nullptr) +// && (Libs::notify_notification_set_urgency != nullptr) +// && (Libs::notify_notification_set_icon_from_pixbuf != nullptr) + && (Libs::notify_notification_set_image_from_pixbuf != nullptr) +// && (Libs::notify_notification_set_hint != nullptr) +// && (Libs::notify_notification_set_hint_int32 != nullptr) +// && (Libs::notify_notification_set_hint_uint32 != nullptr) +// && (Libs::notify_notification_set_hint_double != nullptr) + && (Libs::notify_notification_set_hint_string != nullptr) +// && (Libs::notify_notification_set_hint_byte != nullptr) +// && (Libs::notify_notification_set_hint_byte_array != nullptr) +// && (Libs::notify_notification_clear_hints != nullptr) + && (Libs::notify_notification_add_action != nullptr) + && (Libs::notify_notification_clear_actions != nullptr) + && (Libs::notify_notification_close != nullptr) + && (Libs::notify_notification_get_closed_reason != nullptr) + && (Libs::g_object_ref_sink != nullptr) + && (Libs::g_object_unref != nullptr) + && (Libs::g_list_free_full != nullptr) + && (Libs::g_error_free != nullptr) + && (Libs::g_signal_connect_data != nullptr) + && (Libs::g_signal_handler_disconnect != nullptr) +// && (Libs::gdk_pixbuf_new_from_data != nullptr) + && (Libs::gdk_pixbuf_new_from_file != nullptr); +} + +QString escapeNotificationHtml(QString text) { + text = text.replace(QChar('<'), qstr("<")); + text = text.replace(QChar('>'), qstr(">")); + text = text.replace(QChar('&'), qstr("&")); + return text; +} + +class NotificationData { +public: + NotificationData(const QString &title, const QString &body, const QStringList &capabilities, PeerId peerId, MsgId msgId) + : _data(Libs::notify_notification_new(title.toUtf8().constData(), body.toUtf8().constData(), nullptr)) { + if (valid()) { + init(capabilities, peerId, msgId); + } + } + bool valid() const { + return (_data != nullptr); + } + NotificationData(const NotificationData &other) = delete; + NotificationData &operator=(const NotificationData &other) = delete; + NotificationData(NotificationData &&other) = delete; + NotificationData &operator=(NotificationData &&other) = delete; + + void setImage(const QString &imagePath) { + auto imagePathNative = QFile::encodeName(imagePath); + if (auto pixbuf = Libs::gdk_pixbuf_new_from_file(imagePathNative.constData(), nullptr)) { + Libs::notify_notification_set_image_from_pixbuf(_data, pixbuf); + Libs::g_object_unref(Libs::g_object_cast(pixbuf)); + } + } + bool show() { + if (valid()) { + GError *error = nullptr; + Libs::notify_notification_show(_data, &error); + if (!error) { + return true; + } + + logError(error); + } + return false; + } + + bool close() { + if (valid()) { + GError *error = nullptr; + Libs::notify_notification_close(_data, &error); + if (!error) { + return true; + } + + logError(error); + } + return false; + } + + ~NotificationData() { + if (valid()) { +// if (_handlerId > 0) { +// Libs::g_signal_handler_disconnect(Libs::g_object_cast(_data), _handlerId); +// } +// Libs::notify_notification_clear_actions(_data); + Libs::g_object_unref(Libs::g_object_cast(_data)); + } + } + +private: + void init(const QStringList &capabilities, PeerId peerId, MsgId msgId) { + if (capabilities.contains(qsl("append"))) { + Libs::notify_notification_set_hint_string(_data, "append", "true"); + } else if (capabilities.contains(qsl("x-canonical-append"))) { + Libs::notify_notification_set_hint_string(_data, "x-canonical-append", "true"); + } + + auto signalReceiver = Libs::g_object_cast(_data); + auto signalHandler = G_CALLBACK(NotificationData::notificationClosed); + auto signalName = "closed"; + auto signalDataFreeMethod = &NotificationData::notificationDataFreeClosure; + auto signalData = new NotificationDataStruct(peerId, msgId); + _handlerId = Libs::g_signal_connect_helper(signalReceiver, signalName, signalHandler, signalData, signalDataFreeMethod); + + Libs::notify_notification_set_timeout(_data, Libs::NOTIFY_EXPIRES_DEFAULT); + + if (auto manager = ManagerInstance.data()) { + if (manager->hasActionsSupport()) { + auto label = lang(lng_notification_reply).toUtf8(); + auto actionReceiver = _data; + auto actionHandler = &NotificationData::notificationClicked; + auto actionLabel = label.constData(); + auto actionName = "default"; + auto actionDataFreeMethod = &NotificationData::notificationDataFree; + auto actionData = new NotificationDataStruct(peerId, msgId); + Libs::notify_notification_add_action(actionReceiver, actionName, actionLabel, actionHandler, actionData, actionDataFreeMethod); + } + } + } + + void logError(GError *error) { + LOG(("LibNotify Error: domain %1, code %2, message '%3'").arg(error->domain).arg(error->code).arg(QString::fromUtf8(error->message))); + Libs::g_error_free(error); + } + + struct NotificationDataStruct { + NotificationDataStruct(PeerId peerId, MsgId msgId) : peerId(peerId), msgId(msgId) { + } + + PeerId peerId = 0; + MsgId msgId = 0; + }; + static void notificationDataFree(gpointer data) { + auto notificationData = static_cast(data); + delete notificationData; + } + static void notificationDataFreeClosure(gpointer data, GClosure *closure) { + auto notificationData = static_cast(data); + delete notificationData; + } + static void notificationClosed(Libs::NotifyNotification *notification, gpointer data) { + auto closedReason = Libs::notify_notification_get_closed_reason(notification); + auto notificationData = static_cast(data); + if (auto manager = ManagerInstance.data()) { + manager->clearNotification(notificationData->peerId, notificationData->msgId); + } + } + static void notificationClicked(Libs::NotifyNotification *notification, char *action, gpointer data) { + auto notificationData = static_cast(data); + if (auto manager = ManagerInstance.data()) { + manager->notificationActivated(notificationData->peerId, notificationData->msgId); + } + } + + Libs::NotifyNotification *_data = nullptr; + gulong _handlerId = 0; + +}; + +using Notification = QSharedPointer; + +} // namespace + +void start() { + if (LibNotifyLoaded()) { + if (Libs::notify_is_initted() || Libs::notify_init("Telegram Desktop")) { + ManagerInstance.makeIfNull(); + if (!ManagerInstance->init()) { + ManagerInstance.clear(); + LOG(("LibNotify Error: manager failed to init!")); + } + } else { + LOG(("LibNotify Error: failed to init!")); + } + } +} + +Manager *manager() { + if (Global::started() && Global::NativeNotifications()) { + return ManagerInstance.data(); + } + return nullptr; +} + +bool supported() { + return ManagerInstance.data() != nullptr; +} + +void finish() { + if (manager()) { + ManagerInstance.reset(); + Libs::notify_uninit(); + } +} + +class Manager::Impl { +public: + bool init(); + + void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton); + void clearAll(); + void clearFromHistory(History *history); + void clearNotification(PeerId peerId, MsgId msgId); + + bool hasPoorSupport() const { + return _poorSupported; + } + bool hasActionsSupport() const { + return _actionsSupported; + } + +private: + void showNextNotification(); + + struct QueuedNotification { + PeerData *peer = nullptr; + MsgId msgId = 0; + QString title; + QString body; + bool hideNameAndPhoto = false; + }; + + QString _serverName; + QStringList _capabilities; + + using QueuedNotifications = QList; + QueuedNotifications _queuedNotifications; + + using Notifications = QMap>; + Notifications _notifications; + + Window::Notifications::CachedUserpics _cachedUserpics; + bool _actionsSupported = false; + bool _markupSupported = false; + bool _poorSupported = false; + +}; + +bool Manager::Impl::init() { + if (auto capabilities = Libs::notify_get_server_caps()) { + for (auto capability = capabilities; capability; capability = capability->next) { + auto capabilityText = QString::fromUtf8(static_cast(capability->data)); + _capabilities.push_back(capabilityText); + } + Libs::g_list_free_full(capabilities, g_free); + + LOG(("LibNotify capabilities: %1").arg(_capabilities.join(qstr(", ")))); + if (_capabilities.contains(qsl("actions"))) { + _actionsSupported = true; + } else if (_capabilities.contains(qsl("body-markup"))) { + _markupSupported = true; + } + } else { + LOG(("LibNotify Error: could not get capabilities!")); + } + + // Unity and other Notify OSD users handle desktop notifications + // extremely poor, even without the ability to close() them. + gchar *name = nullptr; + if (Libs::notify_get_server_info(&name, nullptr, nullptr, nullptr)) { + if (name) { + _serverName = QString::fromUtf8(static_cast(name)); + Libs::g_free(name); + + LOG(("Notifications Server: %1").arg(_serverName)); + if (_serverName == qstr("notify-osd")) { +// _poorSupported = true; + _actionsSupported = false; + } + } else { + LOG(("LibNotify Error: successfully got empty server name!")); + } + } else { + LOG(("LibNotify Error: could not get server name!")); + } + + return !_serverName.isEmpty(); +} + +void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + auto titleText = escapeNotificationHtml(title); + auto subtitleText = escapeNotificationHtml(subtitle); + auto msgText = escapeNotificationHtml(msg); + if (_markupSupported && !subtitleText.isEmpty()) { + subtitleText = qstr("") + subtitleText + qstr(""); + } + auto bodyText = subtitleText.isEmpty() ? msgText : (subtitleText + '\n' + msgText); + + QueuedNotification notification; + notification.peer = peer; + notification.msgId = msgId; + notification.title = titleText; + notification.body = bodyText; + notification.hideNameAndPhoto = hideNameAndPhoto; + _queuedNotifications.push_back(notification); + + showNextNotification(); +} + +void Manager::Impl::showNextNotification() { + // Show only one notification at a time in Unity / Notify OSD. + if (_poorSupported) { + for (auto b = _notifications.begin(); !_notifications.isEmpty() && b->isEmpty();) { + _notifications.erase(b); + } + if (!_notifications.isEmpty()) { + return; + } + } + + QueuedNotification data; + while (!_queuedNotifications.isEmpty()) { + data = _queuedNotifications.front(); + _queuedNotifications.pop_front(); + if (data.peer) { + break; + } + } + if (!data.peer) { + return; + } + + auto peerId = data.peer->id; + auto msgId = data.msgId; + auto notification = MakeShared(data.title, data.body, _capabilities, peerId, msgId); + if (!notification->valid()) { + return; + } + + StorageKey key; + if (data.hideNameAndPhoto) { + key = StorageKey(0, 0); + } else { + key = data.peer->userpicUniqueKey(); + } + notification->setImage(_cachedUserpics.get(key, data.peer)); + + auto i = _notifications.find(peerId); + if (i != _notifications.cend()) { + auto j = i->find(msgId); + if (j != i->cend()) { + auto oldNotification = j.value(); + i->erase(j); + oldNotification->close(); + i = _notifications.find(peerId); + } + } + if (i == _notifications.cend()) { + i = _notifications.insert(peerId, QMap()); + } + _notifications[peerId].insert(msgId, notification); + if (!notification->show()) { + i = _notifications.find(peerId); + if (i != _notifications.cend()) { + i->remove(msgId); + if (i->isEmpty()) _notifications.erase(i); + } + showNextNotification(); + } +} + +void Manager::Impl::clearAll() { + _queuedNotifications.clear(); + + auto temp = base::take(_notifications); + for_const (auto ¬ifications, temp) { + for_const (auto notification, notifications) { + notification->close(); + } + } +} + +void Manager::Impl::clearFromHistory(History *history) { + for (auto i = _queuedNotifications.begin(); i != _queuedNotifications.end();) { + if (i->peer == history->peer) { + i = _queuedNotifications.erase(i); + } else { + ++i; + } + } + + auto i = _notifications.find(history->peer->id); + if (i != _notifications.cend()) { + auto temp = base::take(i.value()); + _notifications.erase(i); + + for_const (auto notification, temp) { + notification->close(); + } + } + + showNextNotification(); +} + +void Manager::Impl::clearNotification(PeerId peerId, MsgId msgId) { + auto i = _notifications.find(peerId); + if (i != _notifications.cend()) { + i.value().remove(msgId); + if (i.value().isEmpty()) { + _notifications.erase(i); + } + } + + showNextNotification(); +} + +Manager::Manager() : _impl(std_::make_unique()) { +} + +bool Manager::init() { + return _impl->init(); +} + +void Manager::clearNotification(PeerId peerId, MsgId msgId) { + _impl->clearNotification(peerId, msgId); +} + +bool Manager::hasPoorSupport() const { + return _impl->hasPoorSupport(); +} + +bool Manager::hasActionsSupport() const { + return _impl->hasActionsSupport(); +} + +Manager::~Manager() = default; + +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, msg, hideNameAndPhoto, hideReplyButton); +} + +void Manager::doClearAllFast() { + _impl->clearAll(); +} + +void Manager::doClearFromHistory(History *history) { + _impl->clearFromHistory(history); +} + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h new file mode 100644 index 0000000000..79f9c0259e --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -0,0 +1,63 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/notifications_manager.h" + +namespace Platform { +namespace Notifications { + +class Manager; + +void start(); +Manager *manager(); +bool supported(); +void finish(); + +inline void defaultNotificationShown(QWidget *widget) { +} + +class Manager : public Window::Notifications::NativeManager { +public: + Manager(); + + bool init(); + + void clearNotification(PeerId peerId, MsgId msgId); + bool hasPoorSupport() const; + bool hasActionsSupport() const; + + ~Manager(); + +protected: + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) override; + void doClearAllFast() override; + void doClearFromHistory(History *history) override; + +private: + class Impl; + friend class Impl; + std_::unique_ptr _impl; + +}; + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.h b/Telegram/SourceFiles/platform/mac/mac_utilities.h similarity index 72% rename from Telegram/SourceFiles/platform/win/windows_toasts.h rename to Telegram/SourceFiles/platform/mac/mac_utilities.h index b271abc4c9..692cd43d15 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.h +++ b/Telegram/SourceFiles/platform/mac/mac_utilities.h @@ -20,19 +20,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "lang.h" + +#include + namespace Platform { -namespace Toasts { -void start(); -void finish(); +inline NSString *Q2NSString(const QString &str) { + return [NSString stringWithUTF8String:str.toUtf8().constData()]; +} +inline NSString *NSlang(LangKey key) { + return Q2NSString(lang(key)); +} +inline QString NS2QString(NSString *str) { + return QString::fromUtf8([str cStringUsingEncoding:NSUTF8StringEncoding]); +} -bool supported(); -bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, const QString &subtitle, const QString &msg); - -// Returns the next ms when clearImages() should be called. -uint64 clearImages(uint64 ms); - -void clearNotifies(PeerId peerId); - -} // namespace Toasts } // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/mac_utilities.mm b/Telegram/SourceFiles/platform/mac/mac_utilities.mm new file mode 100644 index 0000000000..5bd630302a --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/mac_utilities.mm @@ -0,0 +1,19 @@ +/* +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. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "platform/mac/mac_utilities.h" diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 2bbe76dc40..ddbd582a71 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -23,17 +23,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" #include "pspecific_mac_p.h" -class NotifyWindow; - namespace Platform { class MacPrivate : public PsMacWindowPrivate { public: - void activeSpaceChanged(); void darkModeChanged(); - void notifyClicked(unsigned long long peer, int msgid); - void notifyReplied(unsigned long long peer, int msgid, const char *str); }; @@ -70,11 +65,6 @@ public: bool psFilterNativeEvent(void *event); - void psActivateNotify(NotifyWindow *w); - void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(NotifyWindow *w); - void psPlatformNotify(HistoryItem *item, int32 fwdCount); - bool eventFilter(QObject *obj, QEvent *evt) override; void psUpdateCounter(); @@ -90,7 +80,6 @@ public: ~MainWindow(); public slots: - void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psShowTrayMenu(); diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 149e688035..6dd1d6edb1 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -24,6 +24,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "playerwidget.h" #include "historywidget.h" #include "localstorage.h" +#include "window/notifications_manager_default.h" +#include "platform/mac/notifications_manager_mac.h" #include "lang.h" @@ -36,8 +38,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Platform { void MacPrivate::activeSpaceChanged() { - if (App::wnd()) { - App::wnd()->notifyActivateAll(); + if (auto manager = Window::Notifications::Default::manager()) { + manager->enumerateNotifications([](QWidget *widget) { + objc_activateWnd(widget->winId()); + }); } } @@ -45,38 +49,6 @@ void MacPrivate::darkModeChanged() { Notify::unreadCounterUpdated(); } -void MacPrivate::notifyClicked(unsigned long long peer, int msgid) { - History *history = App::history(PeerId(peer)); - - App::wnd()->showFromTray(); - if (App::passcoded()) { - App::wnd()->setInnerFocus(); - App::wnd()->notifyClear(); - } else { - bool tomsg = !history->peer->isUser() && (msgid > 0); - if (tomsg) { - HistoryItem *item = App::histItemById(peerToChannel(PeerId(peer)), MsgId(msgid)); - if (!item || !item->mentionsMe()) { - tomsg = false; - } - } - Ui::showPeerHistory(history, tomsg ? msgid : ShowAtUnreadMsgId); - App::wnd()->notifyClear(history); - } -} - -void MacPrivate::notifyReplied(unsigned long long peer, int msgid, const char *str) { - History *history = App::history(PeerId(peer)); - - MainWidget::MessageToSend message; - message.history = history; - message.textWithTags = { QString::fromUtf8(str), TextWithTags::Tags() }; - message.replyTo = (msgid > 0 && !history->peer->isUser()) ? msgid : 0; - message.silent = false; - message.clearDraft = false; - App::main()->sendMessage(message); -} - MainWindow::MainWindow() : posInited(false) , icon256(qsl(":/gui/art/icon256.png")) @@ -148,10 +120,12 @@ void MainWindow::psUpdateWorkmode() { if (trayIcon) { trayIcon->setContextMenu(0); delete trayIcon; + trayIcon = nullptr; } - trayIcon = 0; } - psUpdateDelegate(); + if (auto manager = Platform::Notifications::manager()) { + manager->updateDelegate(); + } setWindowIcon(wndIcon); } @@ -217,10 +191,6 @@ void MainWindow::psUpdateCounter() { } } -void MainWindow::psUpdateDelegate() { - _private.updateDelegate(); -} - void MainWindow::psInitSize() { setMinimumWidth(st::wndMinWidth); setMinimumHeight(st::wndMinHeight); @@ -463,36 +433,10 @@ void MainWindow::psFlash() { _private.startBounce(); } -void MainWindow::psClearNotifies(PeerId peerId) { - _private.clearNotifies(peerId); -} - -void MainWindow::psActivateNotify(NotifyWindow *w) { - objc_activateWnd(w->winId()); -} - bool MainWindow::psFilterNativeEvent(void *event) { return _private.filterNativeEvent(event); } -void MainWindow::psNotifyShown(NotifyWindow *w) { - w->hide(); - objc_holdOnTop(w->winId()); - w->show(); - psShowOverAll(w, false); -} - -void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { - QString title = (!App::passcoded() && Global::NotifyView() <= dbinvShowName && !Global::ScreenIsLocked()) ? item->history()->peer->name : qsl("Telegram Desktop"); - QString subtitle = (!App::passcoded() && Global::NotifyView() <= dbinvShowName && !Global::ScreenIsLocked()) ? item->notificationHeader() : QString(); - QPixmap pix = (!App::passcoded() && Global::NotifyView() <= dbinvShowName && !Global::ScreenIsLocked()) ? item->history()->peer->genUserpic(st::notifyMacPhotoSize) : QPixmap(); - QString msg = (!App::passcoded() && Global::NotifyView() <= dbinvShowPreview && !Global::ScreenIsLocked()) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview); - - bool withReply = !App::passcoded() && (Global::NotifyView() <= dbinvShowPreview && !Global::ScreenIsLocked()) && item->history()->peer->canWrite(); - - _private.showNotify(item->history()->peer->id, item->id, pix, title, subtitle, msg, withReply); -} - bool MainWindow::eventFilter(QObject *obj, QEvent *evt) { QEvent::Type t = evt->type(); if (t == QEvent::FocusIn || t == QEvent::FocusOut) { diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h new file mode 100644 index 0000000000..17d033d7cc --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h @@ -0,0 +1,56 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/notifications_manager.h" + +namespace Platform { +namespace Notifications { + +class Manager; + +void start(); +Manager *manager(); +void finish(); + +void defaultNotificationShown(QWidget *widget); + +class Manager : public Window::Notifications::NativeManager { +public: + Manager(); + + void updateDelegate(); + + ~Manager(); + +protected: + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) override; + void doClearAllFast() override; + void doClearFromHistory(History *history) override; + +private: + class Impl; + std_::unique_ptr _impl; + +}; + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm new file mode 100644 index 0000000000..a1ddf08964 --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -0,0 +1,230 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "platform/mac/notifications_manager_mac.h" + +#include "pspecific.h" +#include "platform/mac/mac_utilities.h" +#include "styles/style_window.h" + +#include + +namespace { + +NeverFreedPointer ManagerInstance; + +} // namespace + +NSImage *qt_mac_create_nsimage(const QPixmap &pm); + +@interface NotificationDelegate : NSObject { +} + +- (id) init; +- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification; +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; + +@end + +@implementation NotificationDelegate { +} + +- (id) init { + if (self = [super init]) { + } + return self; +} + +- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { + auto manager = ManagerInstance.data(); + if (!manager) { + return; + } + + NSDictionary *notificationUserInfo = [notification userInfo]; + NSNumber *launchIdObject = [notificationUserInfo objectForKey:@"launch"]; + auto notificationLaunchId = launchIdObject ? [launchIdObject unsignedLongLongValue] : 0ULL; + DEBUG_LOG(("Received notification with instance %1").arg(notificationLaunchId)); + if (notificationLaunchId != Global::LaunchId()) { // other app instance notification + return; + } + + NSNumber *peerObject = [notificationUserInfo objectForKey:@"peer"]; + auto notificationPeerId = peerObject ? [peerObject unsignedLongLongValue] : 0ULL; + if (!notificationPeerId) { + return; + } + + NSNumber *msgObject = [notificationUserInfo objectForKey:@"msgid"]; + auto notificationMsgId = msgObject ? [msgObject intValue] : 0; + if (notification.activationType == NSUserNotificationActivationTypeReplied) { + auto notificationReply = QString::fromUtf8([[[notification response] string] UTF8String]); + manager->notificationReplied(notificationPeerId, notificationMsgId, notificationReply); + } else if (notification.activationType == NSUserNotificationActivationTypeContentsClicked) { + manager->notificationActivated(notificationPeerId, notificationMsgId); + } + + [center removeDeliveredNotification: notification]; +} + +- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { + return YES; +} + +@end + +namespace Platform { +namespace Notifications { + +void start() { + if (cPlatform() != dbipMacOld) { + ManagerInstance.makeIfNull(); + } +} + +Manager *manager() { + return ManagerInstance.data(); +} + +void finish() { + ManagerInstance.clear(); +} + +void defaultNotificationShown(QWidget *widget) { + widget->hide(); + objc_holdOnTop(widget->winId()); + widget->show(); + psShowOverAll(widget, false); +} + +class Manager::Impl { +public: + Impl(); + void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton); + void clearAll(); + void clearFromHistory(History *history); + void updateDelegate(); + + ~Impl(); + +private: + NotificationDelegate *_delegate; + +}; + +Manager::Impl::Impl() : _delegate([[NotificationDelegate alloc] init]) { +} + +void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + @autoreleasepool { + + NSUserNotification *notification = [[[NSUserNotification alloc] init] autorelease]; + if ([notification respondsToSelector:@selector(setIdentifier:)]) { + auto identifier = QString::number(Global::LaunchId()) + '_' + QString::number(peer->id) + '_' + QString::number(msgId); + auto identifierValue = Q2NSString(identifier); + [notification setIdentifier:identifierValue]; + } + [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer->id],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:Global::LaunchId()],@"launch",nil]]; + + [notification setTitle:Q2NSString(title)]; + [notification setSubtitle:Q2NSString(subtitle)]; + [notification setInformativeText:Q2NSString(msg)]; + if (!hideNameAndPhoto && [notification respondsToSelector:@selector(setContentImage:)]) { + auto userpic = peer->genUserpic(st::notifyMacPhotoSize); + NSImage *img = [qt_mac_create_nsimage(userpic) autorelease]; + [notification setContentImage:img]; + } + + if (!hideReplyButton && [notification respondsToSelector:@selector(setHasReplyButton:)]) { + [notification setHasReplyButton:YES]; + } + + [notification setSoundName:nil]; + + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center deliverNotification:notification]; + + } +} + +void Manager::Impl::clearAll() { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSArray *notificationsList = [center deliveredNotifications]; + for (id notification in notificationsList) { + NSDictionary *notificationUserInfo = [notification userInfo]; + NSNumber *launchIdObject = [notificationUserInfo objectForKey:@"launch"]; + auto notificationLaunchId = launchIdObject ? [launchIdObject unsignedLongLongValue] : 0ULL; + if (notificationLaunchId == Global::LaunchId()) { + [center removeDeliveredNotification:notification]; + } + } + [center removeAllDeliveredNotifications]; +} + +void Manager::Impl::clearFromHistory(History *history) { + unsigned long long peerId = history->peer->id; + + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSArray *notificationsList = [center deliveredNotifications]; + for (id notification in notificationsList) { + NSDictionary *notificationUserInfo = [notification userInfo]; + NSNumber *launchIdObject = [notificationUserInfo objectForKey:@"launch"]; + NSNumber *peerObject = [notificationUserInfo objectForKey:@"peer"]; + auto notificationLaunchId = launchIdObject ? [launchIdObject unsignedLongLongValue] : 0ULL; + auto notificationPeerId = peerObject ? [peerObject unsignedLongLongValue] : 0ULL; + if (notificationPeerId == peerId && notificationLaunchId == Global::LaunchId()) { + [center removeDeliveredNotification:notification]; + } + } +} + +void Manager::Impl::updateDelegate() { + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center setDelegate:_delegate]; +} + +Manager::Impl::~Impl() { + [_delegate release]; +} + +Manager::Manager() : _impl(std_::make_unique()) { +} + +void Manager::updateDelegate() { + _impl->updateDelegate(); +} + +Manager::~Manager() = default; + +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, msg, hideNameAndPhoto, hideReplyButton); +} + +void Manager::doClearAllFast() { + _impl->clearAll(); +} + +void Manager::doClearFromHistory(History *history) { + _impl->clearFromHistory(history); +} + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/platform_file_dialog.h b/Telegram/SourceFiles/platform/platform_file_dialog.h index c3d91d84eb..29bd064b86 100644 --- a/Telegram/SourceFiles/platform/platform_file_dialog.h +++ b/Telegram/SourceFiles/platform/platform_file_dialog.h @@ -24,7 +24,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #ifdef Q_OS_MAC namespace Platform { - namespace FileDialog { inline bool Supported() { return false; diff --git a/Telegram/SourceFiles/platform/platform_notifications_manager.h b/Telegram/SourceFiles/platform/platform_notifications_manager.h new file mode 100644 index 0000000000..81c10ae29a --- /dev/null +++ b/Telegram/SourceFiles/platform/platform_notifications_manager.h @@ -0,0 +1,31 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#ifdef Q_OS_MAC +#include "platform/mac/notifications_manager_mac.h" +#elif defined Q_OS_LINUX // Q_OS_MAC +#include "platform/linux/notifications_manager_linux.h" +#elif defined Q_OS_WINRT // Q_OS_MAC || Q_OS_LINUX +#include "platform/winrt/notifications_manager_winrt.h" +#elif defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT +#include "platform/win/notifications_manager_win.h" +#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index af4744cb96..489e7b6373 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -21,12 +21,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "platform/win/main_window_win.h" -#include "platform/win/windows_toasts.h" +#include "platform/platform_notifications_manager.h" #include "platform/win/windows_dlls.h" +#include "window/notifications_manager.h" #include "mainwindow.h" #include "application.h" #include "lang.h" #include "localstorage.h" +#include "ui/popupmenu.h" #include @@ -138,24 +140,15 @@ public: } bool init(QColor c) { - _fullsize = st::wndShadow.rect().width(); + _fullsize = st::wndShadow.width(); _shift = st::wndShadowShift; QImage cornersImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied); { Painter p(&cornersImage); - p.drawSprite(0, 0, st::wndShadow); + p.setCompositionMode(QPainter::CompositionMode_Source); + st::wndShadow.paint(p, 0, 0, _fullsize); } if (rtl()) cornersImage = cornersImage.mirrored(true, false); - uchar *bits = cornersImage.bits(); - if (bits) { - for ( - quint32 *p = (quint32*)bits, *end = (quint32*)(bits + cornersImage.byteCount()); - p < end; - ++p - ) { - *p = (*p ^ 0x00ffffff) << 24; - } - } _metaSize = _fullsize + 2 * _shift; _alphas.reserve(_metaSize); @@ -253,6 +246,12 @@ public: SelectObject(dcs[i], bitmaps[i]); } + QStringList alphasForLog; + for_const (auto alpha, _alphas) { + alphasForLog.append(QString::number(alpha)); + } + LOG(("Window Shadow: %1").arg(alphasForLog.join(", "))); + initCorners(); return true; } @@ -618,7 +617,6 @@ MainWindow::MainWindow() if (!_taskbarCreatedMsgId) { _taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated"); } - connect(&ps_cleanNotifyPhotosTimer, SIGNAL(timeout()), this, SLOT(psCleanNotifyPhotos())); } void MainWindow::TaskbarCreated() { @@ -645,22 +643,6 @@ void MainWindow::psShowTrayMenu() { trayIconMenu->popup(QCursor::pos()); } -void MainWindow::psCleanNotifyPhotosIn(int32 dt) { - if (dt < 0) { - if (ps_cleanNotifyPhotosTimer.isActive() && ps_cleanNotifyPhotosTimer.remainingTime() <= -dt) return; - dt = -dt; - } - ps_cleanNotifyPhotosTimer.start(dt); -} - -void MainWindow::psCleanNotifyPhotos() { - auto ms = getms(true); - auto minuntil = Toasts::clearImages(ms); - if (minuntil) { - psCleanNotifyPhotosIn(int32(minuntil - ms)); - } -} - void MainWindow::psRefreshTaskbarIcon() { QWidget *w = new QWidget(this); w->setWindowFlags(::operator|(Qt::Tool, Qt::FramelessWindowHint)); @@ -692,7 +674,6 @@ void MainWindow::psSetupTrayIcon() { psUpdateCounter(); trayIcon->show(); - psUpdateDelegate(); } void MainWindow::psUpdateWorkmode() { @@ -763,9 +744,6 @@ void MainWindow::psUpdateCounter() { SetWindowPos(ps_hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } -void MainWindow::psUpdateDelegate() { -} - namespace { HMONITOR enumMonitor = 0; RECT enumMonitorWork; @@ -821,8 +799,8 @@ void MainWindow::psInitFrameless() { psUpdatedPositionTimer.setSingleShot(true); connect(&psUpdatedPositionTimer, SIGNAL(timeout()), this, SLOT(psSavePosition())); - QPlatformNativeInterface *i = QGuiApplication::platformNativeInterface(); - ps_hWnd = static_cast(i->nativeResourceForWindow(QByteArrayLiteral("handle"), windowHandle())); + auto platformInterface = QGuiApplication::platformNativeInterface(); + ps_hWnd = static_cast(platformInterface->nativeResourceForWindow(QByteArrayLiteral("handle"), windowHandle())); if (!ps_hWnd) return; @@ -832,7 +810,6 @@ void MainWindow::psInitFrameless() { } // RegisterApplicationRestart(NULL, 0); - Toasts::start(); psInitSysMenu(); } @@ -880,17 +857,11 @@ void MainWindow::psUpdatedPosition() { } bool MainWindow::psHasNativeNotifications() { - return Toasts::supported(); + return Notifications::supported(); } Q_DECLARE_METATYPE(QMargins); void MainWindow::psFirstShow() { - if (Toasts::supported()) { - Global::SetCustomNotifies(!Global::WindowsNotifications()); - } else { - Global::SetCustomNotifies(true); - } - _psShadowWindows.init(_shActive); _shadowsWorking = true; @@ -1068,8 +1039,6 @@ MainWindow::~MainWindow() { if (taskbarList) taskbarList.Reset(); - Toasts::finish(); - _shadowsWorking = false; if (ps_menu) DestroyMenu(ps_menu); psDestroyIcons(); @@ -1077,23 +1046,4 @@ MainWindow::~MainWindow() { if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd); } -void MainWindow::psActivateNotify(NotifyWindow *w) { -} - -void MainWindow::psClearNotifies(PeerId peerId) { - Toasts::clearNotifies(peerId); -} - -void MainWindow::psNotifyShown(NotifyWindow *w) { -} - -void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { - QString title = (!App::passcoded() && Global::NotifyView() <= dbinvShowName) ? item->history()->peer->name : qsl("Telegram Desktop"); - QString subtitle = (!App::passcoded() && Global::NotifyView() <= dbinvShowName) ? item->notificationHeader() : QString(); - bool showpix = (!App::passcoded() && Global::NotifyView() <= dbinvShowName); - QString msg = (!App::passcoded() && Global::NotifyView() <= dbinvShowPreview) ? (fwdCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, fwdCount)) : lang(lng_notification_preview); - - Toasts::create(item->history()->peer, item->id, showpix, title, subtitle, msg); -} - } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index c3bca32702..20713abe45 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -21,10 +21,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "window/main_window.h" - #include -class NotifyWindow; +class PopupMenu; namespace Platform { @@ -62,15 +61,9 @@ public: return posInited; } - void psActivateNotify(NotifyWindow *w); - void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(NotifyWindow *w); - void psPlatformNotify(HistoryItem *item, int32 fwdCount); - void psUpdateCounter(); bool psHasNativeNotifications(); - void psCleanNotifyPhotosIn(int32 dt); virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; @@ -106,15 +99,10 @@ public: ~MainWindow(); public slots: - - void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psShowTrayMenu(); - void psCleanNotifyPhotos(); - protected: - bool psHasTrayIcon() const { return trayIcon; } @@ -145,8 +133,6 @@ private: HICON ps_iconSmall = nullptr; HICON ps_iconOverlay = nullptr; - SingleTimer ps_cleanNotifyPhotosTimer; - int _deltaLeft = 0; int _deltaTop = 0; diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp similarity index 78% rename from Telegram/SourceFiles/platform/win/windows_toasts.cpp rename to Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 32ad7aa7e2..337af08cd3 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -19,8 +19,9 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" -#include "platform/win/windows_toasts.h" +#include "platform/win/notifications_manager_win.h" +#include "window/notifications_utilities.h" #include "platform/win/windows_app_user_model_id.h" #include "platform/win/windows_dlls.h" #include "mainwindow.h" @@ -44,10 +45,10 @@ using namespace ABI::Windows::Data::Xml::Dom; using namespace Windows::Foundation; namespace Platform { -namespace Toasts { +namespace Notifications { namespace { -bool _supported = false; +NeverFreedPointer ManagerInstance; ComPtr _notificationManager; ComPtr _notifier; @@ -62,13 +63,6 @@ struct NotificationPtr { }; using Notifications = QMap>; Notifications _notifications; -struct Image { - uint64 until; - QString path; -}; -using Images = QMap; -Images _images; -bool _imageSavedFlag = false; class StringReferenceWrapper { public: @@ -152,76 +146,9 @@ bool init() { if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &_notificationFactory))) { return false; } - QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); return true; } -} // namespace - -void start() { - _supported = init(); -} - -bool supported() { - return _supported; -} - -uint64 clearImages(uint64 ms) { - uint64 result = 0; - for (auto i = _images.begin(); i != _images.end();) { - if (!i->until) { - ++i; - continue; - } - if (i->until <= ms) { - QFile(i->path).remove(); - i = _images.erase(i); - } else { - if (!result) { - result = i->until; - } else { - accumulate_min(result, i->until); - } - ++i; - } - } - return result; -} - -void clearNotifies(PeerId peerId) { - if (!_notifier) return; - - if (peerId) { - auto i = _notifications.find(peerId); - if (i != _notifications.cend()) { - auto temp = createAndSwap(i.value()); - _notifications.erase(i); - - for (auto j = temp.cbegin(), e = temp.cend(); j != e; ++j) { - _notifier->Hide(j->p.Get()); - } - } - } else { - auto temp = createAndSwap(_notifications); - for_const (auto ¬ifications, temp) { - for_const (auto ¬ification, notifications) { - _notifier->Hide(notification.p.Get()); - } - } - } -} - -void finish() { - _notifications.clear(); - if (_notificationManager) _notificationManager.Reset(); - if (_notifier) _notifier.Reset(); - if (_notificationFactory) _notificationFactory.Reset(); - - if (_imageSavedFlag) { - psDeleteDir(cWorkingDir() + qsl("tdata/temp")); - } -} - HRESULT SetNodeValueString(_In_ HSTRING inputString, _In_ IXmlNode *node, _In_ IXmlDocument *xml) { ComPtr inputText; @@ -308,7 +235,6 @@ typedef ABI::Windows::Foundation::ITypedEventHandler { public: - ToastEventHandler::ToastEventHandler(const PeerId &peer, MsgId msg) : _ref(1), _peerId(peer), _msgId(msg) { } ~ToastEventHandler() { @@ -316,32 +242,8 @@ public: // DesktopToastActivatedEventHandler IFACEMETHODIMP Invoke(_In_ IToastNotification *sender, _In_ IInspectable* args) { - auto i = _notifications.find(_peerId); - if (i != _notifications.cend()) { - i.value().remove(_msgId); - if (i.value().isEmpty()) { - _notifications.erase(i); - } - } - if (App::wnd()) { - History *history = App::history(_peerId); - - App::wnd()->showFromTray(); - if (App::passcoded()) { - App::wnd()->setInnerFocus(); - App::wnd()->notifyClear(); - } else { - bool tomsg = !history->peer->isUser() && (_msgId > 0); - if (tomsg) { - HistoryItem *item = App::histItemById(peerToChannel(_peerId), _msgId); - if (!item || !item->mentionsMe()) { - tomsg = false; - } - } - Ui::showPeerHistory(history, tomsg ? _msgId : ShowAtUnreadMsgId); - App::wnd()->notifyClear(history); - } - SetForegroundWindow(App::wnd()->psHwnd()); + if (auto manager = ManagerInstance.data()) { + manager->notificationActivated(_peerId, _msgId); } return S_OK; } @@ -356,13 +258,9 @@ public: case ToastDismissalReason_UserCanceled: case ToastDismissalReason_TimedOut: default: - auto i = _notifications.find(_peerId); - if (i != _notifications.cend()) { - i.value().remove(_msgId); - if (i.value().isEmpty()) { - _notifications.erase(i); + if (auto manager = ManagerInstance.data()) { + manager->clearNotification(_peerId, _msgId); } - } break; } } @@ -371,12 +269,8 @@ public: // DesktopToastFailedEventHandler IFACEMETHODIMP Invoke(_In_ IToastNotification *sender, _In_ IToastFailedEventArgs *e) { - auto i = _notifications.find(_peerId); - if (i != _notifications.cend()) { - i.value().remove(_msgId); - if (i.value().isEmpty()) { - _notifications.erase(i); - } + if (auto manager = ManagerInstance.data()) { + manager->clearNotification(_peerId, _msgId); } return S_OK; } @@ -412,42 +306,105 @@ public: } private: - ULONG _ref; PeerId _peerId; MsgId _msgId; + }; -QString getImage(const StorageKey &key, PeerData *peer) { - uint64 ms = getms(true); - auto i = _images.find(key); - if (i != _images.cend()) { - if (i->until) { - i->until = ms + NotifyDeletePhotoAfter; - if (App::wnd()) App::wnd()->psCleanNotifyPhotosIn(-NotifyDeletePhotoAfter); - } - } else { - Image v; - if (key.first) { - v.until = ms + NotifyDeletePhotoAfter; - if (App::wnd()) App::wnd()->psCleanNotifyPhotosIn(-NotifyDeletePhotoAfter); - } else { - v.until = 0; - } - v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(rand_value(), 16) + qsl(".png"); - if (key.first || key.second) { - peer->saveUserpic(v.path, st::notifyMacPhotoSize); - } else { - App::wnd()->iconLarge().save(v.path, "PNG"); - } - i = _images.insert(key, v); - _imageSavedFlag = true; +} // namespace + +void start() { + if (init()) { + ManagerInstance.makeIfNull(); } - return i->path; } -bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, const QString &subtitle, const QString &msg) { - if (!supported() || !_notificationManager || !_notifier || !_notificationFactory) return false; +Manager *manager() { + if (Global::started() && Global::NativeNotifications()) { + return ManagerInstance.data(); + } + return nullptr; +} + +bool supported() { + return ManagerInstance.data() != nullptr; +} + +void finish() { + ManagerInstance.clear(); +} + +class Manager::Impl { +public: + bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton); + void clearAll(); + void clearFromHistory(History *history); + void beforeNotificationActivated(PeerId peerId, MsgId msgId); + void afterNotificationActivated(PeerId peerId, MsgId msgId); + void clearNotification(PeerId peerId, MsgId msgId); + + ~Impl(); + +private: + Window::Notifications::CachedUserpics _cachedUserpics; + +}; + +Manager::Impl::~Impl() { + _notifications.clear(); + if (_notificationManager) _notificationManager.Reset(); + if (_notifier) _notifier.Reset(); + if (_notificationFactory) _notificationFactory.Reset(); +} + +void Manager::Impl::clearAll() { + if (!_notifier) return; + + auto temp = base::take(_notifications); + for_const (auto ¬ifications, temp) { + for_const (auto ¬ification, notifications) { + _notifier->Hide(notification.p.Get()); + } + } +} + +void Manager::Impl::clearFromHistory(History *history) { + if (!_notifier) return; + + auto i = _notifications.find(history->peer->id); + if (i != _notifications.cend()) { + auto temp = base::take(i.value()); + _notifications.erase(i); + + for_const (auto ¬ification, temp) { + _notifier->Hide(notification.p.Get()); + } + } +} + +void Manager::Impl::beforeNotificationActivated(PeerId peerId, MsgId msgId) { + clearNotification(peerId, msgId); +} + +void Manager::Impl::afterNotificationActivated(PeerId peerId, MsgId msgId) { + if (auto window = App::wnd()) { + SetForegroundWindow(window->psHwnd()); + } +} + +void Manager::Impl::clearNotification(PeerId peerId, MsgId msgId) { + auto i = _notifications.find(peerId); + if (i != _notifications.cend()) { + i.value().remove(msgId); + if (i.value().isEmpty()) { + _notifications.erase(i); + } + } +} + +bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + if (!_notificationManager || !_notifier || !_notificationFactory) return false; ComPtr toastXml; bool withSubtitle = !subtitle.isEmpty(); @@ -459,16 +416,15 @@ bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, con if (!SUCCEEDED(hr)) return false; StorageKey key; - QString imagePath; - if (showpix) { - key = peer->userpicUniqueKey(); - } else { + if (hideNameAndPhoto) { key = StorageKey(0, 0); + } else { + key = peer->userpicUniqueKey(); } - QString image = getImage(key, peer); - std::wstring wimage = QDir::toNativeSeparators(image).toStdWString(); + auto userpicPath = _cachedUserpics.get(key, peer); + auto userpicPathWide = QDir::toNativeSeparators(userpicPath).toStdWString(); - hr = SetImageSrc(wimage.c_str(), toastXml.Get()); + hr = SetImageSrc(userpicPathWide.c_str(), toastXml.Get()); if (!SUCCEEDED(hr)) return false; ComPtr nodeList; @@ -549,5 +505,34 @@ bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, con return true; } -} // namespace Toasts +Manager::Manager() : _impl(std_::make_unique()) { +} + +void Manager::clearNotification(PeerId peerId, MsgId msgId) { + _impl->clearNotification(peerId, msgId); +} + +Manager::~Manager() = default; + +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, msg, hideNameAndPhoto, hideReplyButton); +} + +void Manager::doClearAllFast() { + _impl->clearAll(); +} + +void Manager::doClearFromHistory(History *history) { + _impl->clearFromHistory(history); +} + +void Manager::onBeforeNotificationActivated(PeerId peerId, MsgId msgId) { + _impl->beforeNotificationActivated(peerId, msgId); +} + +void Manager::onAfterNotificationActivated(PeerId peerId, MsgId msgId) { + _impl->afterNotificationActivated(peerId, msgId); +} + +} // namespace Notifications } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.h b/Telegram/SourceFiles/platform/win/notifications_manager_win.h new file mode 100644 index 0000000000..ae5e396bbb --- /dev/null +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h @@ -0,0 +1,60 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/notifications_manager.h" + +namespace Platform { +namespace Notifications { + +class Manager; + +void start(); +Manager *manager(); +bool supported(); +void finish(); + +inline void defaultNotificationShown(QWidget *widget) { +} + +class Manager : public Window::Notifications::NativeManager { +public: + Manager(); + + void clearNotification(PeerId peerId, MsgId msgId); + + ~Manager(); + +protected: + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) override; + void doClearAllFast() override; + void doClearFromHistory(History *history) override; + void onBeforeNotificationActivated(PeerId peerId, MsgId msgId) override; + void onAfterNotificationActivated(PeerId peerId, MsgId msgId) override; + +private: + class Impl; + std_::unique_ptr _impl; + +}; + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/profile/profile_actions_widget.cpp b/Telegram/SourceFiles/profile/profile_actions_widget.cpp index f8c04ae0f9..ef4ee8465d 100644 --- a/Telegram/SourceFiles/profile/profile_actions_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_actions_widget.cpp @@ -115,7 +115,7 @@ void ActionsWidget::resizeButton(Ui::LeftOutlineButton *button, int newWidth, in } void ActionsWidget::refreshButtons() { - auto buttons = createAndSwap(_buttons); + auto buttons = base::take(_buttons); for_const (auto &button, buttons) { delete button; } diff --git a/Telegram/SourceFiles/profile/profile_cover.cpp b/Telegram/SourceFiles/profile/profile_cover.cpp index a30bc20be8..d9ac7434d2 100644 --- a/Telegram/SourceFiles/profile/profile_cover.cpp +++ b/Telegram/SourceFiles/profile/profile_cover.cpp @@ -67,7 +67,8 @@ CoverWidget::CoverWidget(QWidget *parent, PeerData *peer) : TWidget(parent) auto observeEvents = ButtonsUpdateFlags | UpdateFlag::NameChanged - | UpdateFlag::UserOnlineChanged; + | UpdateFlag::UserOnlineChanged + | UpdateFlag::MembersChanged; subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) { notifyPeerUpdated(update); })); @@ -336,7 +337,7 @@ void CoverWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) { if (update.flags & UpdateFlag::NameChanged) { refreshNameText(); } - if (update.flags & UpdateFlag::UserOnlineChanged) { + if (update.flags & (UpdateFlag::UserOnlineChanged | UpdateFlag::MembersChanged)) { refreshStatusText(); } } @@ -443,7 +444,7 @@ void CoverWidget::setChannelButtons() { } void CoverWidget::clearButtons() { - auto buttons = createAndSwap(_buttons); + auto buttons = base::take(_buttons); for_const (auto button, buttons) { delete button.widget; delete button.replacement; diff --git a/Telegram/SourceFiles/profile/profile_members_widget.cpp b/Telegram/SourceFiles/profile/profile_members_widget.cpp index 665b4dc015..022f967724 100644 --- a/Telegram/SourceFiles/profile/profile_members_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_members_widget.cpp @@ -593,7 +593,7 @@ void MembersWidget::onUpdateOnlineDisplay() { } MembersWidget::~MembersWidget() { - auto members = createAndSwap(_membersByUser); + auto members = base::take(_membersByUser); for_const (auto member, members) { delete member; } diff --git a/Telegram/SourceFiles/pspecific_mac.cpp b/Telegram/SourceFiles/pspecific_mac.cpp index 2ed9fd9b75..cf6a12e4af 100644 --- a/Telegram/SourceFiles/pspecific_mac.cpp +++ b/Telegram/SourceFiles/pspecific_mac.cpp @@ -478,12 +478,12 @@ QString strNotificationAboutThemeChange() { QString strNotificationAboutScreenLocked() { const uint32 letters[] = { 0x22008263, 0x0800DB6F, 0x45004F6D, 0xCC00972E, 0x0E00A861, 0x9700D970, 0xA100D570, 0x8900686C, 0xB300B365, 0xFE00DE2E, 0x76009B73, 0xFA00BF63, 0xE000A772, 0x9C009F65, 0x4E006065, 0xD900426E, 0xB7007849, 0x64006473, 0x6700824C, 0xE300706F, 0x7C00A063, 0x8F00D76B, 0x04001C65, 0x1C00A664 }; - return strMakeFromLetters(letters, arraysize(letters)); + return strMakeFromLetters(letters, base::array_size(letters)); } QString strNotificationAboutScreenUnlocked() { const uint32 letters[] = { 0x9200D763, 0xC8003C6F, 0xD2003F6D, 0x6000012E, 0x36004061, 0x4400E570, 0xA500BF70, 0x2E00796C, 0x4A009E65, 0x2E00612E, 0xC8001D73, 0x57002263, 0xF0005872, 0x49000765, 0xE5008D65, 0xE600D76E, 0xE8007049, 0x19005C73, 0x34009455, 0xB800B36E, 0xF300CA6C, 0x4C00806F, 0x5300A763, 0xD1003B6B, 0x63003565, 0xF800F264 }; - return strMakeFromLetters(letters, arraysize(letters)); + return strMakeFromLetters(letters, base::array_size(letters)); } QString strStyleOfInterface() { diff --git a/Telegram/SourceFiles/pspecific_mac_p.h b/Telegram/SourceFiles/pspecific_mac_p.h index 2cd3098e21..5a613ceeae 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.h +++ b/Telegram/SourceFiles/pspecific_mac_p.h @@ -1,17 +1,17 @@ /* 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. - + Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ @@ -21,17 +21,11 @@ class PsMacWindowData; class PsMacWindowPrivate { public: - PsMacWindowPrivate(); void setWindowBadge(const QString &str); void startBounce(); - void updateDelegate(); - - void showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply); - void clearNotifies(uint64 peer = 0); - void enableShadow(WId winId); bool filterNativeEvent(void *event); @@ -40,10 +34,6 @@ public: } virtual void darkModeChanged() { } - virtual void notifyClicked(unsigned long long peer, int msgid) { - } - virtual void notifyReplied(unsigned long long peer, int msgid, const char *str) { - } ~PsMacWindowPrivate(); diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 72d9d9d48e..3db0755772 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "playerwidget.h" #include "localstorage.h" #include "media/player/media_player_instance.h" +#include "platform/mac/mac_utilities.h" #include "lang.h" @@ -33,6 +34,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include +using Platform::Q2NSString; +using Platform::NSlang; +using Platform::NS2QString; + @interface qVisualize : NSObject { } @@ -105,24 +110,6 @@ ApplicationDelegate *_sharedDelegate = nil; @end -class QNSString { -public: - QNSString(const QString &str) : _str([NSString stringWithUTF8String:str.toUtf8().constData()]) { - } - NSString *s() { - return _str; - } -private: - NSString *_str; -}; - -QNSString objc_lang(LangKey key) { - return QNSString(lang(key)); -} -QString objcString(NSString *str) { - return QString::fromUtf8([str cStringUsingEncoding:NSUTF8StringEncoding]); -} - @interface ObserverHelper : NSObject { } @@ -134,65 +121,35 @@ QString objcString(NSString *str) { @end -@interface NotifyHandler : NSObject { -} - -- (id) init:(PsMacWindowPrivate *)aWnd; - -- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification; - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification; - -@end - class PsMacWindowData { public: + PsMacWindowData(PsMacWindowPrivate *wnd) : + wnd(wnd), + observerHelper([[ObserverHelper alloc] init:wnd]) { + } - PsMacWindowData(PsMacWindowPrivate *wnd) : - wnd(wnd), - observerHelper([[ObserverHelper alloc] init:wnd]), - notifyHandler([[NotifyHandler alloc] init:wnd]) { - } + ~PsMacWindowData() { + [observerHelper release]; + } - void onNotifyClick(NSUserNotification *notification) { - NSDictionary *dict = [notification userInfo]; - NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"]; - unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0; - int msgId = msgObj ? [msgObj intValue] : 0; - wnd->notifyClicked(peerLong, msgId); - } + PsMacWindowPrivate *wnd; + ObserverHelper *observerHelper; - void onNotifyReply(NSUserNotification *notification) { - NSDictionary *dict = [notification userInfo]; - NSNumber *peerObj = [dict objectForKey:@"peer"], *msgObj = [dict objectForKey:@"msgid"]; - unsigned long long peerLong = peerObj ? [peerObj unsignedLongLongValue] : 0; - int msgId = msgObj ? [msgObj intValue] : 0; - wnd->notifyReplied(peerLong, msgId, [[[notification response] string] UTF8String]); - } - - ~PsMacWindowData() { - [observerHelper release]; - [notifyHandler release]; - } - - PsMacWindowPrivate *wnd; - ObserverHelper *observerHelper; - NotifyHandler *notifyHandler; }; @implementation ObserverHelper { - PsMacWindowPrivate *wnd; + PsMacWindowPrivate *wnd; } - (id) init:(PsMacWindowPrivate *)aWnd { - if (self = [super init]) { - wnd = aWnd; - } - return self; + if (self = [super init]) { + wnd = aWnd; + } + return self; } - (void) activeSpaceDidChange:(NSNotification *)aNotification { - wnd->activeSpaceChanged(); + wnd->activeSpaceChanged(); } - (void) darkModeChanged:(NSNotification *)aNotification { @@ -209,72 +166,49 @@ public: @end -@implementation NotifyHandler { - PsMacWindowPrivate *wnd; -} - -- (id) init:(PsMacWindowPrivate *)aWnd { - if (self = [super init]) { - wnd = aWnd; - } - return self; -} - -- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { - NSNumber *instObj = [[notification userInfo] objectForKey:@"launch"]; - unsigned long long instLong = instObj ? [instObj unsignedLongLongValue] : 0; - DEBUG_LOG(("Received notification with instance %1").arg(instLong)); - if (instLong != Global::LaunchId()) { // other app instance notification - return; - } - if (notification.activationType == NSUserNotificationActivationTypeReplied) { - wnd->data->onNotifyReply(notification); - } else if (notification.activationType == NSUserNotificationActivationTypeContentsClicked) { - wnd->data->onNotifyClick(notification); - } - [center removeDeliveredNotification: notification]; -} - -- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification { - return YES; -} - -@end - PsMacWindowPrivate::PsMacWindowPrivate() : data(new PsMacWindowData(this)) { - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:data->observerHelper selector:@selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(darkModeChanged:) name:QNSString(strNotificationAboutThemeChange()).s() object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(screenIsLocked:) name:QNSString(strNotificationAboutScreenLocked()).s() object:nil]; - [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(screenIsUnlocked:) name:QNSString(strNotificationAboutScreenUnlocked()).s() object:nil]; + @autoreleasepool { + + [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:data->observerHelper selector:@selector(activeSpaceDidChange:) name:NSWorkspaceActiveSpaceDidChangeNotification object:nil]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(darkModeChanged:) name:Q2NSString(strNotificationAboutThemeChange()) object:nil]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(screenIsLocked:) name:Q2NSString(strNotificationAboutScreenLocked()) object:nil]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:data->observerHelper selector:@selector(screenIsUnlocked:) name:Q2NSString(strNotificationAboutScreenUnlocked()) object:nil]; + + } } void PsMacWindowPrivate::setWindowBadge(const QString &str) { - [[NSApp dockTile] setBadgeLabel:QNSString(str).s()]; + @autoreleasepool { + + [[NSApp dockTile] setBadgeLabel:Q2NSString(str)]; + + } } void PsMacWindowPrivate::startBounce() { - [NSApp requestUserAttention:NSInformationalRequest]; -} - -void PsMacWindowPrivate::updateDelegate() { - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - [center setDelegate:data->notifyHandler]; + [NSApp requestUserAttention:NSInformationalRequest]; } void objc_holdOnTop(WId winId) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd setHidesOnDeactivate:NO]; + NSWindow *wnd = [reinterpret_cast(winId) window]; + [wnd setHidesOnDeactivate:NO]; } bool objc_darkMode() { + bool result = false; + @autoreleasepool { + NSDictionary *dict = [[NSUserDefaults standardUserDefaults] persistentDomainForName:NSGlobalDomain]; - id style = [dict objectForKey:QNSString(strStyleOfInterface()).s()]; + id style = [dict objectForKey:Q2NSString(strStyleOfInterface())]; BOOL darkModeOn = (style && [style isKindOfClass:[NSString class]] && NSOrderedSame == [style caseInsensitiveCompare:@"dark"]); - return darkModeOn ? true : false; + result = darkModeOn ? true : false; + + } + return result; } void objc_showOverAll(WId winId, bool canFocus) { - NSWindow *wnd = [reinterpret_cast(winId) window]; + NSWindow *wnd = [reinterpret_cast(winId) window]; [wnd setLevel:NSPopUpMenuWindowLevel]; if (!canFocus) { [wnd setStyleMask:NSUtilityWindowMask | NSNonactivatingPanelMask]; @@ -288,42 +222,13 @@ void objc_bringToBack(WId winId) { } void objc_activateWnd(WId winId) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd orderFront:wnd]; -} - -NSImage *qt_mac_create_nsimage(const QPixmap &pm); - -void PsMacWindowPrivate::showNotify(uint64 peer, int32 msgId, const QPixmap &pix, const QString &title, const QString &subtitle, const QString &msg, bool withReply) { - NSUserNotification *notification = [[NSUserNotification alloc] init]; - NSImage *img = qt_mac_create_nsimage(pix); - - DEBUG_LOG(("Sending notification with userinfo: peer %1, msgId %2 and instance %3").arg(peer).arg(msgId).arg(Global::LaunchId())); - [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer],@"peer",[NSNumber numberWithInt:msgId],@"msgid",[NSNumber numberWithUnsignedLongLong:Global::LaunchId()],@"launch",nil]]; - - [notification setTitle:QNSString(title).s()]; - [notification setSubtitle:QNSString(subtitle).s()]; - [notification setInformativeText:QNSString(msg).s()]; - if ([notification respondsToSelector:@selector(setContentImage:)]) { - [notification setContentImage:img]; - } - - if (withReply && [notification respondsToSelector:@selector(setHasReplyButton:)]) { - [notification setHasReplyButton:YES]; - } - - [notification setSoundName:nil]; - - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - [center deliverNotification:notification]; - - if (img) [img release]; - [notification release]; + NSWindow *wnd = [reinterpret_cast(winId) window]; + [wnd orderFront:wnd]; } void PsMacWindowPrivate::enableShadow(WId winId) { -// [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask]; -// [[(NSView*)winId window] setHasShadow:YES]; +// [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask]; +// [[(NSView*)winId window] setHasShadow:YES]; } bool PsMacWindowPrivate::filterNativeEvent(void *event) { @@ -366,32 +271,24 @@ bool PsMacWindowPrivate::filterNativeEvent(void *event) { return false; } - -void PsMacWindowPrivate::clearNotifies(unsigned long long peer) { - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - if (peer) { - NSArray *notifies = [center deliveredNotifications]; - for (id notify in notifies) { - NSDictionary *dict = [notify userInfo]; - if ([[dict objectForKey:@"peer"] unsignedLongLongValue] == peer && [[dict objectForKey:@"launch"] unsignedLongLongValue] == Global::LaunchId()) { - [center removeDeliveredNotification:notify]; - } - } - } else { - [center removeAllDeliveredNotifications]; - } -} - void objc_debugShowAlert(const QString &str) { - [[NSAlert alertWithMessageText:@"Debug Message" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", QNSString(str).s()] runModal]; + @autoreleasepool { + + [[NSAlert alertWithMessageText:@"Debug Message" defaultButton:@"OK" alternateButton:nil otherButton:nil informativeTextWithFormat:@"%@", Q2NSString(str)] runModal]; + + } } void objc_outputDebugString(const QString &str) { - NSLog(@"%@", QNSString(str).s()); + @autoreleasepool { + + NSLog(@"%@", Q2NSString(str)); + + } } PsMacWindowPrivate::~PsMacWindowPrivate() { - delete data; + delete data; } bool objc_idleSupported() { @@ -400,52 +297,52 @@ bool objc_idleSupported() { } bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinteractions/tint/issues/53 - CFMutableDictionaryRef properties = 0; - CFTypeRef obj; - mach_port_t masterPort; - io_iterator_t iter; - io_registry_entry_t curObj; + CFMutableDictionaryRef properties = 0; + CFTypeRef obj; + mach_port_t masterPort; + io_iterator_t iter; + io_registry_entry_t curObj; - IOMasterPort(MACH_PORT_NULL, &masterPort); + IOMasterPort(MACH_PORT_NULL, &masterPort); - /* Get IOHIDSystem */ - IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); - if (iter == 0) { - return false; - } else { - curObj = IOIteratorNext(iter); - } - if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { - obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); - CFRetain(obj); - } else { - return false; - } + /* Get IOHIDSystem */ + IOServiceGetMatchingServices(masterPort, IOServiceMatching("IOHIDSystem"), &iter); + if (iter == 0) { + return false; + } else { + curObj = IOIteratorNext(iter); + } + if (IORegistryEntryCreateCFProperties(curObj, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties != NULL) { + obj = CFDictionaryGetValue(properties, CFSTR("HIDIdleTime")); + CFRetain(obj); + } else { + return false; + } - uint64 err = ~0L, result = err; - if (obj) { - CFTypeID type = CFGetTypeID(obj); + uint64 err = ~0L, result = err; + if (obj) { + CFTypeID type = CFGetTypeID(obj); - if (type == CFDataGetTypeID()) { - CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(result)), (UInt8*)&result); - } else if (type == CFNumberGetTypeID()) { - CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &result); - } else { - // error - } + if (type == CFDataGetTypeID()) { + CFDataGetBytes((CFDataRef) obj, CFRangeMake(0, sizeof(result)), (UInt8*)&result); + } else if (type == CFNumberGetTypeID()) { + CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &result); + } else { + // error + } - CFRelease(obj); + CFRelease(obj); - if (result != err) { - result /= 1000000; // return as ms - } - } else { - // error - } + if (result != err) { + result /= 1000000; // return as ms + } + } else { + // error + } - CFRelease((CFTypeRef)properties); - IOObjectRelease(curObj); - IOObjectRelease(iter); + CFRelease((CFTypeRef)properties); + IOObjectRelease(curObj); + IOObjectRelease(iter); if (result == err) return false; idleTime = int64(result); @@ -518,7 +415,7 @@ bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinter } - (id) init:(NSString*)file { - toOpen = file; + toOpen = [file retain]; if (self = [super init]) { NSURL *url = [NSURL fileURLWithPath:file]; defUrl = [[NSWorkspace sharedWorkspace] URLForApplicationToOpenURL:url]; @@ -603,7 +500,7 @@ bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinter } [menu insertItem:[NSMenuItem separatorItem] atIndex:index++]; } - NSMenuItem *item = [menu insertItemWithTitle:objc_lang(lng_mac_choose_program_menu).s() action:@selector(itemChosen:) keyEquivalent:@"" atIndex:index++]; + NSMenuItem *item = [menu insertItemWithTitle:NSlang(lng_mac_choose_program_menu) action:@selector(itemChosen:) keyEquivalent:@"" atIndex:index++]; [item setTarget:self]; [menu popUpMenuPositioningItem:nil atLocation:CGPointMake(x, y) inView:nil]; @@ -628,22 +525,24 @@ bool objc_idleTime(int64 &idleTime) { // taken from https://github.com/trueinter if (url) { [[NSWorkspace sharedWorkspace] openFile:toOpen withApplication:[url path]]; } else { - objc_openFile(objcString(toOpen), true); + objc_openFile(NS2QString(toOpen), true); } } - (void) dealloc { - if (apps) [apps release]; - [super dealloc]; + [toOpen release]; if (menu) [menu release]; + [super dealloc]; } @end bool objc_showOpenWithMenu(int x, int y, const QString &f) { - NSString *file = QNSString(f).s(); + @autoreleasepool { + + NSString *file = Q2NSString(f); @try { - OpenFileWithInterface *menu = [[OpenFileWithInterface alloc] init:file]; + OpenFileWithInterface *menu = [[[OpenFileWithInterface alloc] init:file] autorelease]; QRect r = QApplication::desktop()->screenGeometry(QPoint(x, y)); y = r.y() + r.height() - y; return !![menu popupAtX:x andY:y]; @@ -651,12 +550,18 @@ bool objc_showOpenWithMenu(int x, int y, const QString &f) { @catch (NSException *exception) { } @finally { + } + } return false; } void objc_showInFinder(const QString &file, const QString &path) { - [[NSWorkspace sharedWorkspace] selectFile:QNSString(file).s() inFileViewerRootedAtPath:QNSString(path).s()]; + @autoreleasepool { + + [[NSWorkspace sharedWorkspace] selectFile:Q2NSString(file) inFileViewerRootedAtPath:Q2NSString(path)]; + + } } @interface NSURL(CompareUrls) @@ -668,13 +573,13 @@ void objc_showInFinder(const QString &file, const QString &path) { @implementation NSURL(CompareUrls) - (BOOL) isEquivalent:(NSURL *)aURL { - if ([self isEqual:aURL]) return YES; - if ([[self scheme] caseInsensitiveCompare:[aURL scheme]] != NSOrderedSame) return NO; - if ([[self host] caseInsensitiveCompare:[aURL host]] != NSOrderedSame) return NO; - if ([[self path] compare:[aURL path]] != NSOrderedSame) return NO; - if ([[self port] compare:[aURL port]] != NSOrderedSame) return NO; - if ([[self query] compare:[aURL query]] != NSOrderedSame) return NO; - return YES; + if ([self isEqual:aURL]) return YES; + if ([[self scheme] caseInsensitiveCompare:[aURL scheme]] != NSOrderedSame) return NO; + if ([[self host] caseInsensitiveCompare:[aURL host]] != NSOrderedSame) return NO; + if ([[self path] compare:[aURL path]] != NSOrderedSame) return NO; + if ([[self port] compare:[aURL port]] != NSOrderedSame) return NO; + if ([[self query] compare:[aURL query]] != NSOrderedSame) return NO; + return YES; } @end @@ -691,260 +596,267 @@ void objc_showInFinder(const QString &file, const QString &path) { @end @implementation ChooseApplicationDelegate { - BOOL onlyRecommended; - NSArray *apps; - NSOpenPanel *panel; - NSPopUpButton *selector; - NSTextField *good, *bad; - NSImageView *icon; - NSString *recom; - NSView *accessory; + BOOL onlyRecommended; + NSArray *apps; + NSOpenPanel *panel; + NSPopUpButton *selector; + NSTextField *good, *bad; + NSImageView *icon; + NSString *recom; + NSView *accessory; } - (id) init:(NSArray *)recommendedApps withPanel:(NSOpenPanel *)creator withSelector:(NSPopUpButton *)menu withGood:(NSTextField *)goodLabel withBad:(NSTextField *)badLabel withIcon:(NSImageView *)badIcon withAccessory:(NSView *)acc { - if (self = [super init]) { - onlyRecommended = YES; - recom = [objc_lang(lng_mac_recommended_apps).s() copy]; - apps = recommendedApps; - panel = creator; - selector = menu; - good = goodLabel; - bad = badLabel; - icon = badIcon; - accessory = acc; - [selector setAction:@selector(menuDidClose)]; - } - return self; + if (self = [super init]) { + onlyRecommended = YES; + recom = [NSlang(lng_mac_recommended_apps) copy]; + apps = recommendedApps; + panel = creator; + selector = menu; + good = goodLabel; + bad = badLabel; + icon = badIcon; + accessory = acc; + [selector setAction:@selector(menuDidClose)]; + } + return self; } - (BOOL) isRecommended:(NSURL *)url { - if (apps) { - for (id app in apps) { - if ([(NSURL*)app isEquivalent:url]) { - return YES; - } - } - } - return NO; + if (apps) { + for (id app in apps) { + if ([(NSURL*)app isEquivalent:url]) { + return YES; + } + } + } + return NO; } - (BOOL) panel:(id)sender shouldEnableURL:(NSURL *)url { - NSNumber *isDirectory; - if ([url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil] && isDirectory != nil && [isDirectory boolValue]) { - if (onlyRecommended) { - CFStringRef ext = CFURLCopyPathExtension((CFURLRef)url); - NSNumber *isPackage; - if ([url getResourceValue:&isPackage forKey:NSURLIsPackageKey error:nil] && isPackage != nil && [isPackage boolValue]) { - return [self isRecommended:url]; - } - } - return YES; - } - return NO; + NSNumber *isDirectory; + if ([url getResourceValue:&isDirectory forKey:NSURLIsDirectoryKey error:nil] && isDirectory != nil && [isDirectory boolValue]) { + if (onlyRecommended) { + CFStringRef ext = CFURLCopyPathExtension((CFURLRef)url); + NSNumber *isPackage; + if ([url getResourceValue:&isPackage forKey:NSURLIsPackageKey error:nil] && isPackage != nil && [isPackage boolValue]) { + return [self isRecommended:url]; + } + } + return YES; + } + return NO; } - (void) panelSelectionDidChange:(id)sender { - NSArray *urls = [panel URLs]; - if ([urls count]) { - if ([self isRecommended:[urls firstObject]]) { - [bad removeFromSuperview]; - [icon removeFromSuperview]; - [accessory addSubview:good]; - } else { - [good removeFromSuperview]; - [accessory addSubview:bad]; - [accessory addSubview:icon]; - } - } else { - [good removeFromSuperview]; - [bad removeFromSuperview]; - [icon removeFromSuperview]; - } + NSArray *urls = [panel URLs]; + if ([urls count]) { + if ([self isRecommended:[urls firstObject]]) { + [bad removeFromSuperview]; + [icon removeFromSuperview]; + [accessory addSubview:good]; + } else { + [good removeFromSuperview]; + [accessory addSubview:bad]; + [accessory addSubview:icon]; + } + } else { + [good removeFromSuperview]; + [bad removeFromSuperview]; + [icon removeFromSuperview]; + } } - (void) menuDidClose { - onlyRecommended = [[[selector selectedItem] title] isEqualToString:recom]; - [self refreshPanelTable]; + onlyRecommended = [[[selector selectedItem] title] isEqualToString:recom]; + [self refreshPanelTable]; } - (BOOL) refreshDataInViews: (NSArray*)subviews { - for (id view in subviews) { - NSString *cls = [view className]; - if ([cls isEqualToString:QNSString(strNeedToReload()).s()]) { - [view reloadData]; - } else if ([cls isEqualToString:QNSString(strNeedToRefresh1()).s()] || [cls isEqualToString:QNSString(strNeedToRefresh2()).s()]) { - [view reloadData]; - return YES; - } else { - NSArray *next = [view subviews]; - if ([next count] && [self refreshDataInViews:next]) { - return YES; - } - } - } - - return NO; + for (id view in subviews) { + NSString *cls = [view className]; + if ([cls isEqualToString:Q2NSString(strNeedToReload())]) { + [view reloadData]; + } else if ([cls isEqualToString:Q2NSString(strNeedToRefresh1())] || [cls isEqualToString:Q2NSString(strNeedToRefresh2())]) { + [view reloadData]; + return YES; + } else { + NSArray *next = [view subviews]; + if ([next count] && [self refreshDataInViews:next]) { + return YES; + } + } + } + return NO; } - (void) refreshPanelTable { - [self refreshDataInViews:[[panel contentView] subviews]]; - [panel validateVisibleColumns]; + @autoreleasepool { + + [self refreshDataInViews:[[panel contentView] subviews]]; + [panel validateVisibleColumns]; + + } } - (void) dealloc { - if (apps) { - [apps release]; - [recom release]; - } - [super dealloc]; + if (apps) { + [apps release]; + [recom release]; + } + [super dealloc]; } @end void objc_openFile(const QString &f, bool openwith) { - NSString *file = QNSString(f).s(); - if (openwith || [[NSWorkspace sharedWorkspace] openFile:file] == NO) { - @try { - NSURL *url = [NSURL fileURLWithPath:file]; - NSString *ext = [url pathExtension]; - NSArray *names =[url pathComponents]; - NSString *name = [names count] ? [names lastObject] : @""; - NSArray *apps = (NSArray*)LSCopyApplicationURLsForURL(CFURLRef(url), kLSRolesAll); + @autoreleasepool { - NSOpenPanel *openPanel = [NSOpenPanel openPanel]; + NSString *file = Q2NSString(f); + if (openwith || [[NSWorkspace sharedWorkspace] openFile:file] == NO) { + @try { + NSURL *url = [NSURL fileURLWithPath:file]; + NSString *ext = [url pathExtension]; + NSArray *names = [url pathComponents]; + NSString *name = [names count] ? [names lastObject] : @""; + NSArray *apps = (NSArray*)LSCopyApplicationURLsForURL(CFURLRef(url), kLSRolesAll); + + NSOpenPanel *openPanel = [NSOpenPanel openPanel]; NSRect fullRect = { { 0., 0. }, { st::macAccessoryWidth, st::macAccessoryHeight } }; NSView *accessory = [[NSView alloc] initWithFrame:fullRect]; - [accessory setAutoresizesSubviews:YES]; + [accessory setAutoresizesSubviews:YES]; - NSPopUpButton *selector = [[NSPopUpButton alloc] init]; - [accessory addSubview:selector]; - [selector addItemWithTitle:objc_lang(lng_mac_recommended_apps).s()]; - [selector addItemWithTitle:objc_lang(lng_mac_all_apps).s()]; - [selector sizeToFit]; + NSPopUpButton *selector = [[NSPopUpButton alloc] init]; + [accessory addSubview:selector]; + [selector addItemWithTitle:NSlang(lng_mac_recommended_apps)]; + [selector addItemWithTitle:NSlang(lng_mac_all_apps)]; + [selector sizeToFit]; - NSTextField *enableLabel = [[NSTextField alloc] init]; - [accessory addSubview:enableLabel]; - [enableLabel setStringValue:objc_lang(lng_mac_enable_filter).s()]; - [enableLabel setFont:[selector font]]; - [enableLabel setBezeled:NO]; - [enableLabel setDrawsBackground:NO]; - [enableLabel setEditable:NO]; - [enableLabel setSelectable:NO]; - [enableLabel sizeToFit]; + NSTextField *enableLabel = [[NSTextField alloc] init]; + [accessory addSubview:enableLabel]; + [enableLabel setStringValue:NSlang(lng_mac_enable_filter)]; + [enableLabel setFont:[selector font]]; + [enableLabel setBezeled:NO]; + [enableLabel setDrawsBackground:NO]; + [enableLabel setEditable:NO]; + [enableLabel setSelectable:NO]; + [enableLabel sizeToFit]; - NSRect selectorFrame = [selector frame], enableFrame = [enableLabel frame]; - enableFrame.size.width += st::macEnableFilterAdd; - enableFrame.origin.x = (fullRect.size.width - selectorFrame.size.width - enableFrame.size.width) / 2.; - selectorFrame.origin.x = (fullRect.size.width - selectorFrame.size.width + enableFrame.size.width) / 2.; - enableFrame.origin.y = fullRect.size.height - selectorFrame.size.height - st::macEnableFilterTop + (selectorFrame.size.height - enableFrame.size.height) / 2.; - selectorFrame.origin.y = fullRect.size.height - selectorFrame.size.height - st::macSelectorTop; - [enableLabel setFrame:enableFrame]; - [enableLabel setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; - [selector setFrame:selectorFrame]; - [selector setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; + NSRect selectorFrame = [selector frame], enableFrame = [enableLabel frame]; + enableFrame.size.width += st::macEnableFilterAdd; + enableFrame.origin.x = (fullRect.size.width - selectorFrame.size.width - enableFrame.size.width) / 2.; + selectorFrame.origin.x = (fullRect.size.width - selectorFrame.size.width + enableFrame.size.width) / 2.; + enableFrame.origin.y = fullRect.size.height - selectorFrame.size.height - st::macEnableFilterTop + (selectorFrame.size.height - enableFrame.size.height) / 2.; + selectorFrame.origin.y = fullRect.size.height - selectorFrame.size.height - st::macSelectorTop; + [enableLabel setFrame:enableFrame]; + [enableLabel setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; + [selector setFrame:selectorFrame]; + [selector setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; - NSButton *button = [[NSButton alloc] init]; - [accessory addSubview:button]; - [button setButtonType:NSSwitchButton]; - [button setFont:[selector font]]; - [button setTitle:objc_lang(lng_mac_always_open_with).s()]; - [button sizeToFit]; - NSRect alwaysRect = [button frame]; - alwaysRect.origin.x = (fullRect.size.width - alwaysRect.size.width) / 2; - alwaysRect.origin.y = selectorFrame.origin.y - alwaysRect.size.height - st::macAlwaysThisAppTop; - [button setFrame:alwaysRect]; - [button setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; + NSButton *button = [[NSButton alloc] init]; + [accessory addSubview:button]; + [button setButtonType:NSSwitchButton]; + [button setFont:[selector font]]; + [button setTitle:NSlang(lng_mac_always_open_with)]; + [button sizeToFit]; + NSRect alwaysRect = [button frame]; + alwaysRect.origin.x = (fullRect.size.width - alwaysRect.size.width) / 2; + alwaysRect.origin.y = selectorFrame.origin.y - alwaysRect.size.height - st::macAlwaysThisAppTop; + [button setFrame:alwaysRect]; + [button setAutoresizingMask:NSViewMinXMargin|NSViewMaxXMargin]; #ifdef OS_MAC_STORE - [button setHidden:YES]; + [button setHidden:YES]; #endif // OS_MAC_STORE - NSTextField *goodLabel = [[NSTextField alloc] init]; - [goodLabel setStringValue:QNSString(lng_mac_this_app_can_open(lt_file, objcString(name))).s()]; - [goodLabel setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - [goodLabel setBezeled:NO]; - [goodLabel setDrawsBackground:NO]; - [goodLabel setEditable:NO]; - [goodLabel setSelectable:NO]; - [goodLabel sizeToFit]; - NSRect goodFrame = [goodLabel frame]; - goodFrame.origin.x = (fullRect.size.width - goodFrame.size.width) / 2.; - goodFrame.origin.y = alwaysRect.origin.y - goodFrame.size.height - st::macAppHintTop; - [goodLabel setFrame:goodFrame]; + NSTextField *goodLabel = [[NSTextField alloc] init]; + [goodLabel setStringValue:Q2NSString(lng_mac_this_app_can_open(lt_file, NS2QString(name)))]; + [goodLabel setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; + [goodLabel setBezeled:NO]; + [goodLabel setDrawsBackground:NO]; + [goodLabel setEditable:NO]; + [goodLabel setSelectable:NO]; + [goodLabel sizeToFit]; + NSRect goodFrame = [goodLabel frame]; + goodFrame.origin.x = (fullRect.size.width - goodFrame.size.width) / 2.; + goodFrame.origin.y = alwaysRect.origin.y - goodFrame.size.height - st::macAppHintTop; + [goodLabel setFrame:goodFrame]; - NSTextField *badLabel = [[NSTextField alloc] init]; - [badLabel setStringValue:QNSString(lng_mac_not_known_app(lt_file, objcString(name))).s()]; - [badLabel setFont:[goodLabel font]]; - [badLabel setBezeled:NO]; - [badLabel setDrawsBackground:NO]; - [badLabel setEditable:NO]; - [badLabel setSelectable:NO]; - [badLabel sizeToFit]; - NSImageView *badIcon = [[NSImageView alloc] init]; - NSImage *badImage = [NSImage imageNamed:NSImageNameCaution]; - [badIcon setImage:badImage]; - [badIcon setFrame:NSMakeRect(0, 0, st::macCautionIconSize, st::macCautionIconSize)]; + NSTextField *badLabel = [[NSTextField alloc] init]; + [badLabel setStringValue:Q2NSString(lng_mac_not_known_app(lt_file, NS2QString(name)))]; + [badLabel setFont:[goodLabel font]]; + [badLabel setBezeled:NO]; + [badLabel setDrawsBackground:NO]; + [badLabel setEditable:NO]; + [badLabel setSelectable:NO]; + [badLabel sizeToFit]; + NSImageView *badIcon = [[NSImageView alloc] init]; + NSImage *badImage = [NSImage imageNamed:NSImageNameCaution]; + [badIcon setImage:badImage]; + [badIcon setFrame:NSMakeRect(0, 0, st::macCautionIconSize, st::macCautionIconSize)]; - NSRect badFrame = [badLabel frame], badIconFrame = [badIcon frame]; - badFrame.origin.x = (fullRect.size.width - badFrame.size.width + badIconFrame.size.width) / 2.; - badIconFrame.origin.x = (fullRect.size.width - badFrame.size.width - badIconFrame.size.width) / 2.; - badFrame.origin.y = alwaysRect.origin.y - badFrame.size.height - st::macAppHintTop; - badIconFrame.origin.y = badFrame.origin.y; - [badLabel setFrame:badFrame]; - [badIcon setFrame:badIconFrame]; + NSRect badFrame = [badLabel frame], badIconFrame = [badIcon frame]; + badFrame.origin.x = (fullRect.size.width - badFrame.size.width + badIconFrame.size.width) / 2.; + badIconFrame.origin.x = (fullRect.size.width - badFrame.size.width - badIconFrame.size.width) / 2.; + badFrame.origin.y = alwaysRect.origin.y - badFrame.size.height - st::macAppHintTop; + badIconFrame.origin.y = badFrame.origin.y; + [badLabel setFrame:badFrame]; + [badIcon setFrame:badIconFrame]; [openPanel setAccessoryView:accessory]; - ChooseApplicationDelegate *delegate = [[ChooseApplicationDelegate alloc] init:apps withPanel:openPanel withSelector:selector withGood:goodLabel withBad:badLabel withIcon:badIcon withAccessory:accessory]; - [openPanel setDelegate:delegate]; + ChooseApplicationDelegate *delegate = [[ChooseApplicationDelegate alloc] init:apps withPanel:openPanel withSelector:selector withGood:goodLabel withBad:badLabel withIcon:badIcon withAccessory:accessory]; + [openPanel setDelegate:delegate]; - [openPanel setCanChooseDirectories:NO]; - [openPanel setCanChooseFiles:YES]; - [openPanel setAllowsMultipleSelection:NO]; - [openPanel setResolvesAliases:YES]; - [openPanel setTitle:objc_lang(lng_mac_choose_app).s()]; - [openPanel setMessage:QNSString(lng_mac_choose_text(lt_file, objcString(name))).s()]; + [openPanel setCanChooseDirectories:NO]; + [openPanel setCanChooseFiles:YES]; + [openPanel setAllowsMultipleSelection:NO]; + [openPanel setResolvesAliases:YES]; + [openPanel setTitle:NSlang(lng_mac_choose_app)]; + [openPanel setMessage:Q2NSString(lng_mac_choose_text(lt_file, NS2QString(name)))]; - NSArray *appsPaths = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationDirectory inDomains:NSLocalDomainMask]; - if ([appsPaths count]) [openPanel setDirectoryURL:[appsPaths firstObject]]; - [openPanel beginWithCompletionHandler:^(NSInteger result){ - if (result == NSFileHandlingPanelOKButton) { - if ([[openPanel URLs] count] > 0) { - NSURL *app = [[openPanel URLs] objectAtIndex:0]; - NSString *path = [app path]; - if ([button state] == NSOnState) { - NSArray *UTIs = (NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, - (CFStringRef)ext, - nil); - for (NSString *UTI in UTIs) { + NSArray *appsPaths = [[NSFileManager defaultManager] URLsForDirectory:NSApplicationDirectory inDomains:NSLocalDomainMask]; + if ([appsPaths count]) [openPanel setDirectoryURL:[appsPaths firstObject]]; + [openPanel beginWithCompletionHandler:^(NSInteger result){ + if (result == NSFileHandlingPanelOKButton) { + if ([[openPanel URLs] count] > 0) { + NSURL *app = [[openPanel URLs] objectAtIndex:0]; + NSString *path = [app path]; + if ([button state] == NSOnState) { + NSArray *UTIs = (NSArray *)UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, + (CFStringRef)ext, + nil); + for (NSString *UTI in UTIs) { OSStatus result = LSSetDefaultRoleHandlerForContentType((CFStringRef)UTI, kLSRolesAll, (CFStringRef)[[NSBundle bundleWithPath:path] bundleIdentifier]); - DEBUG_LOG(("App Info: set default handler for '%1' UTI result: %2").arg(objcString(UTI)).arg(result)); - } + DEBUG_LOG(("App Info: set default handler for '%1' UTI result: %2").arg(NS2QString(UTI)).arg(result)); + } - [UTIs release]; - } - [[NSWorkspace sharedWorkspace] openFile:file withApplication:[app path]]; - } - } - [selector release]; - [button release]; - [enableLabel release]; - [goodLabel release]; - [badLabel release]; - [badIcon release]; - [accessory release]; - [delegate release]; - }]; - } - @catch (NSException *exception) { - [[NSWorkspace sharedWorkspace] openFile:file]; - } - @finally { - } - } + [UTIs release]; + } + [[NSWorkspace sharedWorkspace] openFile:file withApplication:[app path]]; + } + } + [selector release]; + [button release]; + [enableLabel release]; + [goodLabel release]; + [badLabel release]; + [badIcon release]; + [accessory release]; + [delegate release]; + }]; + } + @catch (NSException *exception) { + [[NSWorkspace sharedWorkspace] openFile:file]; + } + @finally { + } + } + + } } void objc_start() { @@ -975,6 +887,8 @@ void objc_registerCustomScheme() { } BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) { + @autoreleasepool { + NSString *path = @"", *args = @""; @try { path = [[NSBundle mainBundle] bundlePath]; @@ -984,7 +898,7 @@ BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) { } path = [path stringByAppendingString:@"/Contents/Frameworks/Updater"]; - NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:@"-workpath", QNSString(cWorkingDir()).s(), @"-procid", nil]; + NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:@"-workpath", Q2NSString(cWorkingDir()), @"-procid", nil]; [args addObject:[NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]]]; if (cRestartingToSettings()) [args addObject:@"-tosettings"]; if (!update) [args addObject:@"-noupdate"]; @@ -994,26 +908,28 @@ BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) { if (cTestMode()) [args addObject:@"-testmode"]; if (cDataFile() != qsl("data")) { [args addObject:@"-key"]; - [args addObject:QNSString(cDataFile()).s()]; + [args addObject:Q2NSString(cDataFile())]; } if (!crashreport.isEmpty()) { [args addObject:@"-crashreport"]; - [args addObject:QNSString(crashreport).s()]; + [args addObject:Q2NSString(crashreport)]; } - DEBUG_LOG(("Application Info: executing %1 %2").arg(objcString(path)).arg(objcString([args componentsJoinedByString:@" "]))); + DEBUG_LOG(("Application Info: executing %1 %2").arg(NS2QString(path)).arg(NS2QString([args componentsJoinedByString:@" "]))); Logs::closeMain(); SignalHandlers::finish(); if (![NSTask launchedTaskWithLaunchPath:path arguments:args]) { - DEBUG_LOG(("Task not launched while executing %1 %2").arg(objcString(path)).arg(objcString([args componentsJoinedByString:@" "]))); + DEBUG_LOG(("Task not launched while executing %1 %2").arg(NS2QString(path)).arg(NS2QString([args componentsJoinedByString:@" "]))); return NO; } } @catch (NSException *exception) { - LOG(("Exception caught while executing %1 %2").arg(objcString(path)).arg(objcString(args))); + LOG(("Exception caught while executing %1 %2").arg(NS2QString(path)).arg(NS2QString(args))); return NO; } @finally { + } + } return YES; } @@ -1026,8 +942,12 @@ void objc_execTelegram(const QString &crashreport) { #ifndef OS_MAC_STORE _execUpdater(NO, crashreport); #else // OS_MAC_STORE + @autoreleasepool { + NSDictionary *conf = [NSDictionary dictionaryWithObject:[NSArray array] forKey:NSWorkspaceLaunchConfigurationArguments]; - [[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:QNSString(cExeDir() + cExeName()).s()] options:NSWorkspaceLaunchAsync | NSWorkspaceLaunchNewInstance configuration:conf error:0]; + [[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL fileURLWithPath:Q2NSString(cExeDir() + cExeName())] options:NSWorkspaceLaunchAsync | NSWorkspaceLaunchNewInstance configuration:conf error:0]; + + } #endif // OS_MAC_STORE } @@ -1040,7 +960,9 @@ void objc_activateProgram(WId winId) { } bool objc_moveFile(const QString &from, const QString &to) { - NSString *f = QNSString(from).s(), *t = QNSString(to).s(); + @autoreleasepool { + + NSString *f = Q2NSString(from), *t = Q2NSString(to); if ([[NSFileManager defaultManager] fileExistsAtPath:t]) { NSData *data = [NSData dataWithContentsOfFile:f]; if (data) { @@ -1055,11 +977,17 @@ bool objc_moveFile(const QString &from, const QString &to) { return true; } } + + } return false; } void objc_deleteDir(const QString &dir) { - [[NSFileManager defaultManager] removeItemAtPath:QNSString(dir).s() error:nil]; + @autoreleasepool { + + [[NSFileManager defaultManager] removeItemAtPath:Q2NSString(dir) error:nil]; + + } } double objc_appkitVersion() { @@ -1093,20 +1021,20 @@ QString objc_downloadPath() { QString objc_currentCountry() { NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale. NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; - return countryCode ? objcString(countryCode) : QString(); + return countryCode ? NS2QString(countryCode) : QString(); } QString objc_currentLang() { NSLocale *currentLocale = [NSLocale currentLocale]; // get the current locale. NSString *currentLang = [currentLocale objectForKey:NSLocaleLanguageCode]; - return currentLang ? objcString(currentLang) : QString(); + return currentLang ? NS2QString(currentLang) : QString(); } QString objc_convertFileUrl(const QString &url) { NSString *nsurl = [[[NSURL URLWithString: [NSString stringWithUTF8String: (qsl("file://") + url).toUtf8().constData()]] filePathURL] path]; if (!nsurl) return QString(); - return objcString(nsurl); + return NS2QString(nsurl); } QByteArray objc_downloadPathBookmark(const QString &path) { @@ -1150,7 +1078,7 @@ void objc_downloadPathEnableAccess(const QByteArray &bookmark) { } _downloadPathUrl = url; - Global::SetDownloadPath(objcString([_downloadPathUrl path]) + '/'); + Global::SetDownloadPath(NS2QString([_downloadPathUrl path]) + '/'); if (isStale) { NSData *data = [_downloadPathUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&error]; if (data) { @@ -1191,7 +1119,7 @@ objc_FileBookmark::objc_FileBookmark(const QByteArray &bookmark) { if ([url startAccessingSecurityScopedResource]) { data = new objc_FileBookmarkData(); data->url = [url retain]; - data->name = objcString([url path]); + data->name = NS2QString([url path]); data->bookmark = bookmark; [url stopAccessingSecurityScopedResource]; } diff --git a/Telegram/SourceFiles/pspecific_win.cpp b/Telegram/SourceFiles/pspecific_win.cpp index 61fcde541b..72ade2e76e 100644 --- a/Telegram/SourceFiles/pspecific_win.cpp +++ b/Telegram/SourceFiles/pspecific_win.cpp @@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "pspecific.h" #include "platform/win/main_window_win.h" -#include "platform/win/windows_toasts.h" +#include "platform/win/notifications_manager_win.h" #include "platform/win/windows_app_user_model_id.h" #include "platform/win/windows_dlls.h" #include "platform/win/windows_event_filter.h" diff --git a/Telegram/SourceFiles/pspecific_winrt.h b/Telegram/SourceFiles/pspecific_winrt.h index 06722c1abb..30ab755d5f 100644 --- a/Telegram/SourceFiles/pspecific_winrt.h +++ b/Telegram/SourceFiles/pspecific_winrt.h @@ -27,7 +27,11 @@ inline QString psServerPrefix() { inline void psCheckLocalSocket(const QString &) { } -class NotifyWindow; +namespace Window { +namespace Notifications { +class Widget; +} // namespace Notifications +} // namespace Window class PsMainWindow : public QMainWindow { Q_OBJECT diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index bf41030ca3..0bb31a9a57 100644 --- a/Telegram/SourceFiles/settings/settings.style +++ b/Telegram/SourceFiles/settings/settings.style @@ -125,17 +125,6 @@ settingsLargeSkip: 23px; settingsActionPadding: margins(0px, 4px, 0px, 5px); -settingsSliderHeight: 39px; -settingsSliderTop: 5px; -settingsSliderSkip: 3px; -settingsSliderThickness: 3px; -settingsSliderActiveFg: #4bb5e7; -settingsSliderInactiveFg: #e1eaef; -settingsSliderLabelTop: 17px; -settingsSliderLabelFont: normalFont; -settingsSliderLabelFg: #1485c2; -settingsSliderDuration: 200; - settingsBackgroundSize: 120px; settingsUpdateFg: #999999; diff --git a/Telegram/SourceFiles/settings/settings_general_widget.cpp b/Telegram/SourceFiles/settings/settings_general_widget.cpp index 4945dd5c8c..9c5e66c59f 100644 --- a/Telegram/SourceFiles/settings/settings_general_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_general_widget.cpp @@ -193,6 +193,9 @@ void GeneralWidget::refreshControls() { style::margins marginLink(st::defaultBoxCheckbox.textPosition.x(), 0, 0, st::settingsSkip); addChildRow(_updateRow, marginLink, slidedPadding); connect(_updateRow->entity(), SIGNAL(restart()), this, SLOT(onRestart())); + if (!cAutoUpdate()) { + _updateRow->hideFast(); + } #endif // TDESKTOP_DISABLE_AUTOUPDATE if (cPlatform() == dbipWindows || cSupportTray()) { diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 86c34889c1..6aa9c61b18 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -27,6 +27,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/widgets/widget_slide_wrap.h" #include "ui/flatcheckbox.h" #include "mainwindow.h" +#include "window/notifications_manager.h" +#include "boxes/notifications_box.h" namespace Settings { @@ -57,13 +59,35 @@ void NotificationsWidget::createControls() { _showSenderName->hideFast(); _showMessagePreview->hideFast(); } -#ifdef Q_OS_WIN - if (App::wnd()->psHasNativeNotifications()) { - addChildRow(_windowsNative, margin, lang(lng_settings_use_windows), SLOT(onWindowsNative()), Global::WindowsNotifications()); - } -#endif // Q_OS_WIN addChildRow(_playSound, margin, lang(lng_settings_sound_notify), SLOT(onPlaySound()), Global::SoundNotify()); addChildRow(_includeMuted, margin, lang(lng_settings_include_muted), SLOT(onIncludeMuted()), Global::IncludeMuted()); + + if (cPlatform() != dbipMac) { + createNotificationsControls(); + } +} + +void NotificationsWidget::createNotificationsControls() { + style::margins margin(0, 0, 0, st::settingsSkip); + style::margins slidedPadding(0, margin.bottom() / 2, 0, margin.bottom() - (margin.bottom() / 2)); + + QString nativeNotificationsLabel; +#ifdef Q_OS_WIN + if (App::wnd()->psHasNativeNotifications()) { + nativeNotificationsLabel = lang(lng_settings_use_windows); + } +#elif defined Q_OS_LINUX64 || defined Q_OS_LINUX32 + if (App::wnd()->psHasNativeNotifications()) { + nativeNotificationsLabel = lang(lng_settings_use_native_notifications); + } +#endif // Q_OS_WIN + if (!nativeNotificationsLabel.isEmpty()) { + addChildRow(_nativeNotifications, margin, nativeNotificationsLabel, SLOT(onNativeNotifications()), Global::NativeNotifications()); + } + addChildRow(_advanced, margin, slidedPadding, lang(lng_settings_advanced_notifications), SLOT(onAdvanced())); + if (!nativeNotificationsLabel.isEmpty() && Global::NativeNotifications()) { + _advanced->hideFast(); + } } void NotificationsWidget::onDesktopNotifications() { @@ -131,17 +155,24 @@ void NotificationsWidget::viewParamUpdated() { } } -void NotificationsWidget::onWindowsNative() { -#ifdef Q_OS_WIN - if (Global::WindowsNotifications() == _windowsNative->checked()) { +void NotificationsWidget::onNativeNotifications() { + if (Global::NativeNotifications() == _nativeNotifications->checked()) { return; } - Global::SetWindowsNotifications(_windowsNative->checked()); - Global::SetCustomNotifies(!Global::WindowsNotifications()); + Window::Notifications::manager()->clearAllFast(); + Global::SetNativeNotifications(_nativeNotifications->checked()); Local::writeUserSettings(); - Global::RefNotifySettingsChanged().notify(Notify::ChangeType::UseNative); -#endif // Q_OS_WIN + + if (Global::NativeNotifications()) { + _advanced->slideUp(); + } else { + _advanced->slideDown(); + } +} + +void NotificationsWidget::onAdvanced() { + Ui::showLayer(new NotificationsBox()); } void NotificationsWidget::onPlaySound() { diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.h b/Telegram/SourceFiles/settings/settings_notifications_widget.h index 7625a76b7a..5bc3c28d9d 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.h +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.h @@ -34,21 +34,24 @@ private slots: void onDesktopNotifications(); void onShowSenderName(); void onShowMessagePreview(); - void onWindowsNative(); + void onNativeNotifications(); void onPlaySound(); void onIncludeMuted(); + void onAdvanced(); private: void createControls(); + void createNotificationsControls(); void desktopEnabledUpdated(); void viewParamUpdated(); ChildWidget _desktopNotifications = { nullptr }; ChildWidget> _showSenderName = { nullptr }; ChildWidget> _showMessagePreview = { nullptr }; - ChildWidget _windowsNative = { nullptr }; + ChildWidget _nativeNotifications = { nullptr }; ChildWidget _playSound = { nullptr }; ChildWidget _includeMuted = { nullptr }; + ChildWidget> _advanced = { nullptr }; }; diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.cpp b/Telegram/SourceFiles/settings/settings_scale_widget.cpp index 4f4f714d13..4d5f913568 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_scale_widget.cpp @@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwindow.h" #include "boxes/confirmbox.h" #include "application.h" +#include "ui/widgets/discrete_slider.h" namespace Settings { namespace { @@ -43,139 +44,6 @@ QString scaleLabel(DBIScale scale) { } // namespace -Slider::Slider(QWidget *parent) : TWidget(parent) -, _a_left(animation(this, &Slider::step_left)) { - setCursor(style::cur_pointer); -} - -void Slider::setActiveSection(int index) { - setSelectedSection(index); - if (_activeIndex != index) { - _activeIndex = index; - emit sectionActivated(); - } -} - -void Slider::setActiveSectionFast(int index) { - setActiveSection(index); - a_left.finish(); - _a_left.stop(); - update(); -} - -void Slider::addSection(const QString &label) { - auto section = Section(label); - _sections.push_back(section); -} - -void Slider::resizeSections(int newWidth) { - auto count = _sections.size(); - if (!count) return; - - auto skips = count - 1; - auto sectionsWidth = newWidth - skips * st::settingsSliderSkip; - auto sectionWidth = sectionsWidth / float64(count); - auto x = 0.; - for (int i = 0; i != count; ++i) { - auto §ion = _sections[i]; - auto skip = i * st::settingsSliderThickness; - section.left = qFloor(x) + skip; - x += sectionWidth; - section.width = qRound(x) - (section.left - skip); - } - a_left = anim::ivalue(_sections[_activeIndex].left, _sections[_activeIndex].left); - _a_left.stop(); -} - -void Slider::mousePressEvent(QMouseEvent *e) { - setSelectedSection(getIndexFromPosition(e->pos())); - _pressed = true; -} - -void Slider::mouseMoveEvent(QMouseEvent *e) { - if (!_pressed) return; - setSelectedSection(getIndexFromPosition(e->pos())); -} - -void Slider::mouseReleaseEvent(QMouseEvent *e) { - if (!_pressed) return; - _pressed = false; - setActiveSection(getIndexFromPosition(e->pos())); -} - -void Slider::setSelectedSection(int index) { - if (index < 0) return; - - if (_selected != index) { - _selected = index; - a_left.start(_sections[_selected].left); - _a_left.start(); - } -} - -void Slider::paintEvent(QPaintEvent *e) { - Painter p(this); - - int activeLeft = a_left.current(); - - p.setFont(st::settingsSliderLabelFont); - p.setPen(st::settingsSliderLabelFg); - for (int i = 0, count = _sections.size(); i != count; ++i) { - auto §ion = _sections.at(i); - auto from = section.left, tofill = section.width; - if (activeLeft > from) { - auto fill = qMin(tofill, activeLeft - from); - p.fillRect(myrtlrect(from, st::settingsSliderTop, fill, st::settingsSliderThickness), st::settingsSliderInactiveFg); - from += fill; - tofill -= fill; - } - if (activeLeft + section.width > from) { - if (auto fill = qMin(tofill, activeLeft + section.width - from)) { - p.fillRect(myrtlrect(from, st::settingsSliderTop, fill, st::settingsSliderThickness), st::settingsSliderActiveFg); - from += fill; - tofill -= fill; - } - } - if (tofill) { - p.fillRect(myrtlrect(from, st::settingsSliderTop, tofill, st::settingsSliderThickness), st::settingsSliderInactiveFg); - } - p.drawTextLeft(section.left + (section.width - section.labelWidth) / 2, st::settingsSliderLabelTop, width(), section.label, section.labelWidth); - } -} - -int Slider::resizeGetHeight(int newWidth) { - resizeSections(newWidth); - return st::settingsSliderHeight; -} - -int Slider::getIndexFromPosition(QPoint pos) { - int count = _sections.size(); - for (int i = 0; i != count; ++i) { - if (_sections[i].left + _sections[i].width > pos.x()) { - return i; - } - } - return count - 1; -} - -void Slider::step_left(float64 ms, bool timer) { - auto dt = ms / st::settingsSliderDuration; - if (dt >= 1) { - a_left.finish(); - _a_left.stop(); - } else { - a_left.update(dt, anim::linear); - } - if (timer) { - update(); - } -} - -Slider::Section::Section(const QString &label) -: label(label) -, labelWidth(st::settingsSliderLabelFont->width(label)) { -} - ScaleWidget::ScaleWidget(QWidget *parent, UserData *self) : BlockWidget(parent, self, lang(lng_settings_section_scale)) { createControls(); } @@ -191,8 +59,7 @@ void ScaleWidget::createControls() { _scale->addSection(scaleLabel(dbisOneAndHalf)); _scale->addSection(scaleLabel(dbisTwo)); _scale->setActiveSectionFast(cEvalScale(cConfigScale()) - 1); - - connect(_scale, SIGNAL(sectionActivated()), this, SLOT(onSectionActivated())); + _scale->setSectionActivatedCallback([this] { scaleChanged(); }); } void ScaleWidget::onAutoChosen() { @@ -234,7 +101,7 @@ void ScaleWidget::setScale(DBIScale newScale) { } } -void ScaleWidget::onSectionActivated() { +void ScaleWidget::scaleChanged() { auto newScale = dbisAuto; switch (_scale->activeSection()) { case 0: newScale = dbisOne; break; diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.h b/Telegram/SourceFiles/settings/settings_scale_widget.h index 1a4485c45b..39684d7549 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.h +++ b/Telegram/SourceFiles/settings/settings_scale_widget.h @@ -24,55 +24,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org class Checkbox; +namespace Ui { +class DiscreteSlider; +} // namespace Ui + namespace Settings { -class Slider : public TWidget { - Q_OBJECT - -public: - Slider(QWidget *parent); - - int activeSection() const { - return _activeIndex; - } - void setActiveSection(int index); - void setActiveSectionFast(int index); - void addSection(const QString &label); - -protected: - void paintEvent(QPaintEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void mouseMoveEvent(QMouseEvent *e) override; - void mouseReleaseEvent(QMouseEvent *e) override; - - int resizeGetHeight(int newWidth) override; - -signals: - void sectionActivated(); - -private: - void resizeSections(int newWidth); - int getIndexFromPosition(QPoint pos); - void setSelectedSection(int index); - void step_left(float64 ms, bool timer); - - struct Section { - Section(const QString &label); - - int left, width; - QString label; - int labelWidth; - }; - QList
_sections; - int _activeIndex = 0; - - bool _pressed = false; - int _selected = 0; - anim::ivalue a_left = { 0 }; - Animation _a_left; - -}; - class ScaleWidget : public BlockWidget { Q_OBJECT @@ -81,15 +38,15 @@ public: private slots: void onAutoChosen(); - void onSectionActivated(); void onRestartNow(); private: + void scaleChanged(); void createControls(); void setScale(DBIScale newScale); ChildWidget _auto = { nullptr }; - ChildWidget _scale = { nullptr }; + ChildWidget _scale = { nullptr }; }; diff --git a/Telegram/SourceFiles/stdafx.h b/Telegram/SourceFiles/stdafx.h index 41c554fad0..5a62d11287 100644 --- a/Telegram/SourceFiles/stdafx.h +++ b/Telegram/SourceFiles/stdafx.h @@ -72,8 +72,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/flatinput.h" #include "ui/flattextarea.h" #include "ui/flatbutton.h" -#include "ui/boxshadow.h" -#include "ui/popupmenu.h" #include "ui/scrollarea.h" #include "ui/images.h" #include "ui/text/text.h" diff --git a/Telegram/SourceFiles/stickers/emoji_pan.cpp b/Telegram/SourceFiles/stickers/emoji_pan.cpp index d7a73e2217..63850ba287 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.cpp +++ b/Telegram/SourceFiles/stickers/emoji_pan.cpp @@ -48,8 +48,8 @@ EmojiColorPicker::EmojiColorPicker() : TWidget() setMouseTracking(true); setFocusPolicy(Qt::NoFocus); - int32 w = st::emojiPanSize.width() * (EmojiColorsCount + 1) + 4 * st::emojiColorsPadding + st::emojiColorsSep + st::dropdownDef.shadow.pxWidth() * 2; - int32 h = 2 * st::emojiColorsPadding + st::emojiPanSize.height() + st::dropdownDef.shadow.pxHeight() * 2; + int32 w = st::emojiPanSize.width() * (EmojiColorsCount + 1) + 4 * st::emojiColorsPadding + st::emojiColorsSep + st::dropdownDef.shadow.width() * 2; + int32 h = 2 * st::emojiColorsPadding + st::emojiPanSize.height() + st::dropdownDef.shadow.height() * 2; resize(w, h); _hideTimer.setSingleShot(true); @@ -84,7 +84,7 @@ void EmojiColorPicker::paintEvent(QPaintEvent *e) { p.setClipRect(e->rect()); } - int32 w = st::dropdownDef.shadow.pxWidth(), h = st::dropdownDef.shadow.pxHeight(); + int32 w = st::dropdownDef.shadow.width(), h = st::dropdownDef.shadow.height(); QRect r = QRect(w, h, width() - 2 * w, height() - 2 * h); _shadow.paint(p, r, st::dropdownDef.shadowShift); @@ -116,6 +116,9 @@ void EmojiColorPicker::leaveEvent(QEvent *e) { } void EmojiColorPicker::mousePressEvent(QMouseEvent *e) { + if (e->button() != Qt::LeftButton) { + return; + } _lastMousePos = e->globalPos(); updateSelected(); _pressedSel = _selected; @@ -174,7 +177,7 @@ void EmojiColorPicker::step_selected(uint64 ms, bool timer) { _hovers[index] = (i.key() > 0) ? dt : (1 - dt); ++i; } - toUpdate += QRect(st::dropdownDef.shadow.pxWidth() + st::emojiColorsPadding + index * st::emojiPanSize.width() + (index ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::dropdownDef.shadow.pxHeight() + st::emojiColorsPadding, st::emojiPanSize.width(), st::emojiPanSize.height()); + toUpdate += QRect(st::dropdownDef.shadow.width() + st::emojiColorsPadding + index * st::emojiPanSize.width() + (index ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::dropdownDef.shadow.height() + st::emojiColorsPadding, st::emojiPanSize.width(), st::emojiPanSize.height()); } if (timer) rtlupdate(toUpdate.boundingRect()); if (_emojiAnimations.isEmpty()) _a_selected.stop(); @@ -191,7 +194,7 @@ void EmojiColorPicker::hideStart(bool fast) { emit hidden(); } else { if (_cache.isNull()) { - int32 w = st::dropdownDef.shadow.pxWidth(), h = st::dropdownDef.shadow.pxHeight(); + int32 w = st::dropdownDef.shadow.width(), h = st::dropdownDef.shadow.height(); _cache = myGrab(this, QRect(w, h, width() - 2 * w, height() - 2 * h)); clearSelection(true); } @@ -213,7 +216,7 @@ void EmojiColorPicker::showStart() { return; } if (_cache.isNull()) { - int32 w = st::dropdownDef.shadow.pxWidth(), h = st::dropdownDef.shadow.pxHeight(); + int32 w = st::dropdownDef.shadow.width(), h = st::dropdownDef.shadow.height(); _cache = myGrab(this, QRect(w, h, width() - 2 * w, height() - 2 * h)); clearSelection(true); } @@ -237,9 +240,9 @@ void EmojiColorPicker::clearSelection(bool fast) { void EmojiColorPicker::updateSelected() { int32 selIndex = -1; QPoint p(mapFromGlobal(_lastMousePos)); - int32 sx = rtl() ? (width() - p.x()) : p.x(), y = p.y() - st::dropdownDef.shadow.pxHeight() - st::emojiColorsPadding; + int32 sx = rtl() ? (width() - p.x()) : p.x(), y = p.y() - st::dropdownDef.shadow.height() - st::emojiColorsPadding; if (y >= 0 && y < st::emojiPanSize.height()) { - int32 x = sx - st::dropdownDef.shadow.pxWidth() - st::emojiColorsPadding; + int32 x = sx - st::dropdownDef.shadow.width() - st::emojiColorsPadding; if (x >= 0 && x < st::emojiPanSize.width()) { selIndex = 0; } else { @@ -275,7 +278,7 @@ void EmojiColorPicker::updateSelected() { void EmojiColorPicker::drawVariant(Painter &p, int variant) { float64 hover = _hovers[variant]; - QPoint w(st::dropdownDef.shadow.pxWidth() + st::emojiColorsPadding + variant * st::emojiPanSize.width() + (variant ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::dropdownDef.shadow.pxHeight() + st::emojiColorsPadding); + QPoint w(st::dropdownDef.shadow.width() + st::emojiColorsPadding + variant * st::emojiPanSize.width() + (variant ? 2 * st::emojiColorsPadding + st::emojiColorsSep : 0), st::dropdownDef.shadow.height() + st::emojiColorsPadding); if (hover > 0) { p.setOpacity(hover); QPoint tl(w); @@ -411,7 +414,7 @@ bool EmojiPanInner::checkPickerHide() { void EmojiPanInner::mousePressEvent(QMouseEvent *e) { _lastMousePos = e->globalPos(); updateSelected(); - if (checkPickerHide()) { + if (checkPickerHide() || e->button() != Qt::LeftButton) { return; } _pressedSel = _selected; @@ -1160,6 +1163,9 @@ QRect StickerPanInner::featuredAddRect(int index) const { } void StickerPanInner::mousePressEvent(QMouseEvent *e) { + if (e->button() != Qt::LeftButton) { + return; + } _lastMousePos = e->globalPos(); updateSelected(); @@ -2419,14 +2425,14 @@ EmojiPanel::EmojiPanel(QWidget *parent, const QString &text, uint64 setId, bool , _setId(setId) , _special(special) , _deleteVisible(false) -, _delete(special ? 0 : new IconedButton(this, st::notifyClose)) { // Stickers::NoneSetId if in emoji +, _delete(special ? 0 : new IconedButton(this, st::simpleClose)) { // Stickers::NoneSetId if in emoji resize(st::emojiPanWidth, st::emojiPanHeader); setMouseTracking(true); setFocusPolicy(Qt::NoFocus); setText(text); if (_delete) { _delete->hide(); - _delete->moveToRight(st::emojiPanHeaderLeft - ((_delete->width() - st::notifyClose.icon.pxWidth()) / 2), (st::emojiPanHeader - _delete->height()) / 2, width()); + _delete->moveToRight(st::emojiPanHeaderLeft - ((_delete->width() - st::simpleClose.icon.pxWidth()) / 2), (st::emojiPanHeader - _delete->height()) / 2, width()); connect(_delete, SIGNAL(clicked()), this, SLOT(onDelete())); } } @@ -2444,7 +2450,7 @@ void EmojiPanel::updateText() { int32 availw = st::emojiPanWidth - st::emojiPanHeaderLeft * 2; if (_deleteVisible) { if (!_special && _setId != Stickers::NoneSetId) { - availw -= st::notifyClose.icon.pxWidth() + st::emojiPanHeaderLeft; + availw -= st::simpleClose.icon.pxWidth() + st::emojiPanHeaderLeft; } } else { auto switchText = ([this]() { @@ -2895,7 +2901,7 @@ void EmojiPan::otherLeave() { } void EmojiPan::mousePressEvent(QMouseEvent *e) { - if (!_stickersShown) return; + if (!_stickersShown || e->button() != Qt::LeftButton) return; _iconsMousePos = e ? e->globalPos() : QCursor::pos(); updateSelected(); diff --git a/Telegram/SourceFiles/stickers/emoji_pan.h b/Telegram/SourceFiles/stickers/emoji_pan.h index 71b542af7f..488f5c86f3 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.h +++ b/Telegram/SourceFiles/stickers/emoji_pan.h @@ -21,7 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "ui/twidget.h" -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" namespace InlineBots { namespace Layout { @@ -108,7 +108,7 @@ private: QTimer _hideTimer; - BoxShadow _shadow; + Ui::RectShadow _shadow; }; @@ -616,7 +616,7 @@ private: QTimer _hideTimer; - BoxShadow _shadow; + Ui::RectShadow _shadow; FlatRadiobutton _recent, _people, _nature, _food, _activity, _travel, _objects, _symbols; QList _icons; diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 4328546dff..1d646dacc6 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -766,7 +766,7 @@ ImagePtr PhotoData::makeReplyPreview() { } PhotoData::~PhotoData() { - deleteAndMark(uploadingData); + delete base::take(uploadingData); } void PhotoOpenClickHandler::onClickImpl() const { @@ -1161,7 +1161,7 @@ void DocumentData::setattributes(const QVector &attributes } } break; case mtpc_documentAttributeVideo: { - const auto &d(attributes[i].c_documentAttributeVideo()); + auto &d = attributes[i].c_documentAttributeVideo(); if (type == FileDocument) { type = VideoDocument; } @@ -1169,7 +1169,7 @@ void DocumentData::setattributes(const QVector &attributes dimensions = QSize(d.vw.v, d.vh.v); } break; case mtpc_documentAttributeAudio: { - const auto &d(attributes[i].c_documentAttributeAudio()); + auto &d = attributes[i].c_documentAttributeAudio(); if (type == FileDocument) { if (d.is_voice()) { type = VoiceDocument; @@ -1428,7 +1428,7 @@ void DocumentData::save(const QString &toFile, ActionOnLoad action, const FullMs void DocumentData::cancel() { if (!loading()) return; - auto loader = createAndSwap(_loader); + auto loader = base::take(_loader); _loader = CancelledMtpFileLoader; loader->cancel(); loader->deleteLater(); diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 31f6acb083..7ca225b330 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -246,7 +246,7 @@ protected: public: virtual ~PeerData() { if (notify != UnknownNotifySettings && notify != EmptyNotifySettings) { - deleteAndMark(notify); + delete base::take(notify); } } diff --git a/Telegram/SourceFiles/sysbuttons.cpp b/Telegram/SourceFiles/sysbuttons.cpp index 7db90ca2f4..f7c1529547 100644 --- a/Telegram/SourceFiles/sysbuttons.cpp +++ b/Telegram/SourceFiles/sysbuttons.cpp @@ -30,7 +30,6 @@ SysBtn::SysBtn(QWidget *parent, const style::sysButton &st, const QString &text) , _st(st) , a_color(_st.color->c) , _a_color(animation(this, &SysBtn::step_color)) -, _overLevel(0) , _text(text) { int32 w = _st.size.width() + (_text.isEmpty() ? 0 : ((_st.size.width() - _st.icon.width()) / 2 + st::titleTextButton.font->width(_text))); resize(w, _st.size.height()); diff --git a/Telegram/SourceFiles/sysbuttons.h b/Telegram/SourceFiles/sysbuttons.h index 784d6900d4..91c7a56d93 100644 --- a/Telegram/SourceFiles/sysbuttons.h +++ b/Telegram/SourceFiles/sysbuttons.h @@ -60,7 +60,7 @@ protected: anim::cvalue a_color; Animation _a_color; - float64 _overLevel; + float64 _overLevel = 0.; QString _text; }; diff --git a/Telegram/SourceFiles/ui/animation.h b/Telegram/SourceFiles/ui/animation.h index 6842c55a7f..1018053f2c 100644 --- a/Telegram/SourceFiles/ui/animation.h +++ b/Telegram/SourceFiles/ui/animation.h @@ -37,7 +37,7 @@ public: } ReaderPointer(const ReaderPointer &other) = delete; ReaderPointer &operator=(const ReaderPointer &other) = delete; - ReaderPointer(ReaderPointer &&other) : _pointer(createAndSwap(other._pointer)) { + ReaderPointer(ReaderPointer &&other) : _pointer(base::take(other._pointer)) { } ReaderPointer &operator=(ReaderPointer &&other) { swap(other); @@ -106,13 +106,12 @@ namespace anim { public: using ValueType = float64; - fvalue() { + fvalue() = default; + fvalue(float64 from) : _cur(from), _from(from) { } - fvalue(const float64 &from) : _cur(from), _from(from), _delta(0) { + fvalue(float64 from, float64 to) : _cur(from), _from(from), _delta(to - from) { } - fvalue(const float64 &from, const float64 &to) : _cur(from), _from(from), _delta(to - from) { - } - void start(const float64 &to) { + void start(float64 to) { _from = _cur; _delta = to - _from; } @@ -120,13 +119,21 @@ namespace anim { _delta = _from + _delta - _cur; _from = _cur; } - const float64 ¤t() const { + + float64 from() const { + return _from; + } + float64 current() const { return _cur; } float64 to() const { return _from + _delta; } - fvalue &update(const float64 &dt, transition func) { + void add(float64 delta) { + _from += delta; + _cur += delta; + } + fvalue &update(float64 dt, transition func) { _cur = _from + (*func)(_delta, dt); return *this; } @@ -137,19 +144,20 @@ namespace anim { } private: - float64 _cur, _from, _delta; + float64 _cur = 0.; + float64 _from = 0.; + float64 _delta = 0.; }; class ivalue { // int animated value public: - using ValueType = int32; + using ValueType = int; - ivalue() { + ivalue() = default; + ivalue(int from) : _cur(from), _from(float64(from)) { } - ivalue(int32 from) : _cur(from), _from(float64(from)), _delta(0) { - } - ivalue(int32 from, int32 to) : _cur(from), _from(float64(from)), _delta(float64(to - from)) { + ivalue(int from, int to) : _cur(from), _from(float64(from)), _delta(float64(to - from)) { } void start(int32 to) { _from = float64(_cur); @@ -159,13 +167,21 @@ namespace anim { _delta = _from + _delta - float64(_cur); _from = float64(_cur); } - int32 current() const { + + int from() const { + return _from; + } + int current() const { return _cur; } - int32 to() const { - return _from + _delta; + int to() const { + return qRound(_from + _delta); } - ivalue &update(const float64 &dt, transition func) { + void add(int delta) { + _from += delta; + _cur += delta; + } + ivalue &update(float64 dt, transition func) { _cur = qRound(_from + (*func)(_delta, dt)); return *this; } @@ -176,8 +192,9 @@ namespace anim { } private: - int32 _cur; - float64 _from, _delta; + int _cur = 0; + float64 _from = 0.; + float64 _delta = 0.; }; @@ -185,15 +202,24 @@ namespace anim { public: using ValueType = QColor; - cvalue() { - } - cvalue(const QColor &from) : _cur(from), _from_r(from.redF()), _from_g(from.greenF()), _from_b(from.blueF()), _from_a(from.alphaF()), _delta_r(0), _delta_g(0), _delta_b(0), _delta_a(0) { + cvalue() = default; + cvalue(const QColor &from) + : _cur(from) + , _from_r(from.redF()) + , _from_g(from.greenF()) + , _from_b(from.blueF()) + , _from_a(from.alphaF()) { } cvalue(const QColor &from, const QColor &to) : _cur(from) - , _from_r(from.redF()), _from_g(from.greenF()), _from_b(from.blueF()), _from_a(from.alphaF()) - , _delta_r(to.redF() - from.redF()), _delta_g(to.greenF() - from.greenF()), _delta_b(to.blueF() - from.blueF()), _delta_a(to.alphaF() - from.alphaF()) - { + , _from_r(from.redF()) + , _from_g(from.greenF()) + , _from_b(from.blueF()) + , _from_a(from.alphaF()) + , _delta_r(to.redF() - from.redF()) + , _delta_g(to.greenF() - from.greenF()) + , _delta_b(to.blueF() - from.blueF()) + , _delta_a(to.alphaF() - from.alphaF()) { } void start(const QColor &to) { _from_r = _cur.redF(); @@ -215,6 +241,14 @@ namespace anim { _from_b = _cur.blueF(); _from_a = _cur.alphaF(); } + QColor from() const { + QColor result; + result.setRedF(_from_r); + result.setGreenF(_from_g); + result.setBlueF(_from_b); + result.setAlphaF(_from_a); + return result; + } const QColor ¤t() const { return _cur; } @@ -247,7 +281,14 @@ namespace anim { private: QColor _cur; - float64 _from_r, _from_g, _from_b, _from_a, _delta_r, _delta_g, _delta_b, _delta_a; + float64 _from_r = 0.; + float64 _from_g = 0.; + float64 _from_b = 0.; + float64 _from_a = 0.; + float64 _delta_r = 0.; + float64 _delta_g = 0.; + float64 _delta_b = 0.; + float64 _delta_a = 0.; }; @@ -282,7 +323,7 @@ public: void start() { _implementation->start(); } void step(Animation *a, uint64 ms, bool timer) { _implementation->step(a, ms, timer); } - ~AnimationCallbacks() { deleteAndMark(_implementation); } + ~AnimationCallbacks() { delete base::take(_implementation); } private: AnimationImplementation *_implementation; diff --git a/Telegram/SourceFiles/ui/boxshadow.cpp b/Telegram/SourceFiles/ui/boxshadow.cpp deleted file mode 100644 index b556d5719f..0000000000 --- a/Telegram/SourceFiles/ui/boxshadow.cpp +++ /dev/null @@ -1,191 +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-2016 John Preston, https://desktop.telegram.org -*/ -#include "stdafx.h" - -#include "boxshadow.h" - -BoxShadow::BoxShadow(const style::sprite &topLeft) : _size(topLeft.pxWidth()), _pixsize(_size * cIntRetinaFactor()) { - if (!_size) return; - - QImage cornersImage(_pixsize * 2, _pixsize * 2, QImage::Format_ARGB32_Premultiplied); - cornersImage.setDevicePixelRatio(cRetinaFactor()); - { - Painter p(&cornersImage); - p.drawSprite(QPoint(rtl() ? _size : 0, 0), topLeft); - } - if (rtl()) cornersImage = cornersImage.mirrored(true, false); - uchar *bits = cornersImage.bits(); - if (bits) { - for ( - quint32 *p = (quint32*)bits, *end = (quint32*)(bits + cornersImage.byteCount()); - p < end; - ++p - ) { - *p = (*p ^ 0x00ffffff) << 24; - } - } - { - QPainter p(&cornersImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - QImage m = cornersImage.mirrored(); - m.setDevicePixelRatio(cRetinaFactor()); - p.drawImage(0, _size, m, 0, _pixsize, _pixsize, _pixsize); - } - { - QPainter p(&cornersImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - QImage m = cornersImage.mirrored(true, false); - m.setDevicePixelRatio(cRetinaFactor()); - p.drawImage(_size, 0, m, _pixsize, 0, _pixsize, _pixsize * 2); - } - _colors.reserve(_pixsize); - uchar prev = 0; - for (int i = 0; i < _pixsize; ++i) { - uchar a = (cornersImage.pixel(QPoint(i, _pixsize - 1)) >> 24); - if (a < prev) break; - - _colors.push_back(style::color(0, 0, 0, a)); - prev = a; - } - if (cRetina()) { - _left = App::pixmapFromImageInPlace(cornersImage.copy(0, _pixsize - 1, _colors.size(), 1)); - _left.setDevicePixelRatio(cRetinaFactor()); - _top = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize - 1, 0, 1, _colors.size())); - _top.setDevicePixelRatio(cRetinaFactor()); - _right = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize * 2 - _colors.size(), _pixsize, _colors.size(), 1)); - _right.setDevicePixelRatio(cRetinaFactor()); - _bottom = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize, _pixsize * 2 - _colors.size(), 1, _colors.size())); - _bottom.setDevicePixelRatio(cRetinaFactor()); - } - _corners = App::pixmapFromImageInPlace(std_::move(cornersImage)); - _corners.setDevicePixelRatio(cRetinaFactor()); -} - -void BoxShadow::paint(QPainter &p, const QRect &box, int32 shifty, int32 flags) { - if (!_size) return; - - int32 rshifty = shifty * cIntRetinaFactor(); - int32 count = _colors.size(), countsize = count / cIntRetinaFactor(), minus = _size - countsize + shifty; - bool left = (flags & Left), top = (flags & Top), right = (flags & Right), bottom = (flags & Bottom); - if (left && top) p.drawPixmap(box.left() - _size + minus, box.top() - _size + minus + shifty, _corners, 0, 0, _pixsize, _pixsize); - if (right && top) p.drawPixmap(box.left() + box.width() - minus, box.top() - _size + minus + shifty, _corners, _pixsize, 0, _pixsize, _pixsize); - if (right && bottom) p.drawPixmap(box.left() + box.width() - minus, box.top() + box.height() - minus + shifty, _corners, _pixsize, _pixsize, _pixsize, _pixsize); - if (left && bottom) p.drawPixmap(box.left() - _size + minus, box.top() + box.height() - minus + shifty, _corners, 0, _pixsize, _pixsize, _pixsize); - if (cRetina()) { - bool wasSmooth = p.renderHints().testFlag(QPainter::SmoothPixmapTransform); - if (wasSmooth) p.setRenderHint(QPainter::SmoothPixmapTransform, false); - if (left) p.drawPixmap(box.left() - countsize + shifty, box.top() + (top ? minus : 0) + shifty, countsize - shifty, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _left, 0, 0, count - rshifty, 1); - if (top) p.drawPixmap(box.left() + (left ? minus : 0), box.top() - countsize + 2 * shifty, box.width() - (right ? minus : 0) - (left ? minus : 0), countsize - 2 * shifty, _top, 0, 0, 1, count - 2 * rshifty); - if (right) p.drawPixmap(box.left() + box.width(), box.top() + (top ? minus : 0) + shifty, countsize - shifty, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _right, rshifty, 0, count - rshifty, 1); - if (bottom) p.drawPixmap(box.left() + (left ? minus : 0), box.top() + box.height(), box.width() - (right ? minus : 0) - (left ? minus : 0), countsize, _bottom, 0, 0, 1, count); - if (wasSmooth) p.setRenderHint(QPainter::SmoothPixmapTransform); - } else { - p.setPen(Qt::NoPen); - for (int32 i = 0; i < count; ++i) { - if (left && i + shifty < count) p.fillRect(box.left() - count + i + shifty, box.top() + (top ? minus : 0) + shifty, 1, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i]->b); - if (top && i + 2 * shifty < count) p.fillRect(box.left() + (left ? minus : 0), box.top() - count + i + 2 * shifty, box.width() - (right ? minus : 0) - (left ? minus : 0), 1, _colors[i]->b); - if (right && i + shifty < count) p.fillRect(box.left() + box.width() + count - i - shifty - 1, box.top() + (top ? minus : 0) + shifty, 1, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _colors[i]->b); - if (bottom) p.fillRect(box.left() + (left ? minus : 0), box.top() + box.height() + count - i - 1, box.width() - (right ? minus : 0) - (left ? minus : 0), 1, _colors[i]->b); - } - } -} - -style::margins BoxShadow::getDimensions(int32 shifty) const { - int32 d = _colors.size() / cIntRetinaFactor(); - return style::margins(d - shifty, d - 2 * shifty, d - shifty, d); -} - -namespace Ui { - -RectShadow::RectShadow(const style::icon &topLeft) : _size(topLeft.width()), _pixsize(_size * cIntRetinaFactor()) { - if (!_size) return; - - QImage cornersImage(_pixsize * 2, _pixsize * 2, QImage::Format_ARGB32_Premultiplied); - cornersImage.setDevicePixelRatio(cRetinaFactor()); - { - Painter p(&cornersImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - topLeft.paint(p, QPoint(0, 0), _size); - } - if (rtl()) cornersImage = cornersImage.mirrored(true, false); - { - QPainter p(&cornersImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - QImage m = cornersImage.mirrored(); - m.setDevicePixelRatio(cRetinaFactor()); - p.drawImage(0, _size, m, 0, _pixsize, _pixsize, _pixsize); - } - { - QPainter p(&cornersImage); - p.setCompositionMode(QPainter::CompositionMode_Source); - QImage m = cornersImage.mirrored(true, false); - m.setDevicePixelRatio(cRetinaFactor()); - p.drawImage(_size, 0, m, _pixsize, 0, _pixsize, _pixsize * 2); - } - - uchar prev = 0; - for (int i = 0; i < _pixsize; ++i) { - uchar a = (cornersImage.pixel(QPoint(i, _pixsize - 1)) >> 24); - if (a < prev) break; - - ++_thickness; - prev = a; - } - - _left = App::pixmapFromImageInPlace(cornersImage.copy(0, _pixsize - 1, _thickness, 1)); - _left.setDevicePixelRatio(cRetinaFactor()); - _top = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize - 1, 0, 1, _thickness)); - _top.setDevicePixelRatio(cRetinaFactor()); - _right = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize * 2 - _thickness, _pixsize, _thickness, 1)); - _right.setDevicePixelRatio(cRetinaFactor()); - _bottom = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize, _pixsize * 2 - _thickness, 1, _thickness)); - _bottom.setDevicePixelRatio(cRetinaFactor()); - - _corners = App::pixmapFromImageInPlace(std_::move(cornersImage)); - _corners.setDevicePixelRatio(cRetinaFactor()); -} - -void RectShadow::paint(Painter &p, const QRect &box, int shifty, Sides sides) { - if (!_size) return; - - int32 rshifty = shifty * cIntRetinaFactor(); - int32 count = _thickness, countsize = count / cIntRetinaFactor(), minus = _size - countsize + shifty; - bool left = (sides & Side::Left), top = (sides & Side::Top), right = (sides & Side::Right), bottom = (sides & Side::Bottom); - if (left && top) p.drawPixmap(box.left() - _size + minus, box.top() - _size + minus + shifty, _corners, 0, 0, _pixsize, _pixsize); - if (right && top) p.drawPixmap(box.left() + box.width() - minus, box.top() - _size + minus + shifty, _corners, _pixsize, 0, _pixsize, _pixsize); - if (right && bottom) p.drawPixmap(box.left() + box.width() - minus, box.top() + box.height() - minus + shifty, _corners, _pixsize, _pixsize, _pixsize, _pixsize); - if (left && bottom) p.drawPixmap(box.left() - _size + minus, box.top() + box.height() - minus + shifty, _corners, 0, _pixsize, _pixsize, _pixsize); - - bool wasSmooth = p.renderHints().testFlag(QPainter::SmoothPixmapTransform); - if (wasSmooth) p.setRenderHint(QPainter::SmoothPixmapTransform, false); - if (left) p.drawPixmap(box.left() - countsize + shifty, box.top() + (top ? minus : 0) + shifty, countsize - shifty, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _left, 0, 0, count - rshifty, 1); - if (top) p.drawPixmap(box.left() + (left ? minus : 0), box.top() - countsize + 2 * shifty, box.width() - (right ? minus : 0) - (left ? minus : 0), countsize - 2 * shifty, _top, 0, 0, 1, count - 2 * rshifty); - if (right) p.drawPixmap(box.left() + box.width(), box.top() + (top ? minus : 0) + shifty, countsize - shifty, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _right, rshifty, 0, count - rshifty, 1); - if (bottom) p.drawPixmap(box.left() + (left ? minus : 0), box.top() + box.height(), box.width() - (right ? minus : 0) - (left ? minus : 0), countsize, _bottom, 0, 0, 1, count); - if (wasSmooth) p.setRenderHint(QPainter::SmoothPixmapTransform); -} - -style::margins RectShadow::getDimensions(int32 shifty) const { - int d = _thickness / cIntRetinaFactor(); - return style::margins(d - shifty, d - 2 * shifty, d - shifty, d); -} - -} // namespace Ui diff --git a/Telegram/SourceFiles/ui/countryinput.h b/Telegram/SourceFiles/ui/countryinput.h index d23e422a34..8292f0187b 100644 --- a/Telegram/SourceFiles/ui/countryinput.h +++ b/Telegram/SourceFiles/ui/countryinput.h @@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/flatinput.h" #include "ui/scrollarea.h" #include "ui/flatbutton.h" -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" #include "boxes/abstractbox.h" QString findValidCode(QString fullCode); diff --git a/Telegram/SourceFiles/ui/effects/fade_animation.cpp b/Telegram/SourceFiles/ui/effects/fade_animation.cpp index 5e2663a5d9..2c5cee26ac 100644 --- a/Telegram/SourceFiles/ui/effects/fade_animation.cpp +++ b/Telegram/SourceFiles/ui/effects/fade_animation.cpp @@ -103,7 +103,7 @@ void FadeAnimation::startAnimation(int duration) { } void FadeAnimation::updateCallback() { - if (_animation.animating(getms())) { + if (_animation.animating()) { _widget->update(); if (_updatedCallback) { _updatedCallback(_animation.current(_visible ? 1. : 0.)); diff --git a/Telegram/SourceFiles/ui/effects/rect_shadow.cpp b/Telegram/SourceFiles/ui/effects/rect_shadow.cpp new file mode 100644 index 0000000000..e50c0bc22e --- /dev/null +++ b/Telegram/SourceFiles/ui/effects/rect_shadow.cpp @@ -0,0 +1,101 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "ui/effects/rect_shadow.h" + +namespace Ui { + +RectShadow::RectShadow(const style::icon &topLeft) : _size(topLeft.width()), _pixsize(_size * cIntRetinaFactor()) { + if (!_size) return; + + QImage cornersImage(_pixsize * 2, _pixsize * 2, QImage::Format_ARGB32_Premultiplied); + cornersImage.setDevicePixelRatio(cRetinaFactor()); + { + Painter p(&cornersImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + topLeft.paint(p, QPoint(0, 0), _size); + } + if (rtl()) cornersImage = cornersImage.mirrored(true, false); + { + QPainter p(&cornersImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + QImage m = cornersImage.mirrored(); + m.setDevicePixelRatio(cRetinaFactor()); + p.drawImage(0, _size, m, 0, _pixsize, _pixsize, _pixsize); + } + { + QPainter p(&cornersImage); + p.setCompositionMode(QPainter::CompositionMode_Source); + QImage m = cornersImage.mirrored(true, false); + m.setDevicePixelRatio(cRetinaFactor()); + p.drawImage(_size, 0, m, _pixsize, 0, _pixsize, _pixsize * 2); + } + + uchar prev = 0; + for (int i = 0; i < _pixsize; ++i) { + uchar a = (cornersImage.pixel(QPoint(i, _pixsize - 1)) >> 24); + if (a < prev) break; + + ++_thickness; + prev = a; + } + + _left = App::pixmapFromImageInPlace(cornersImage.copy(0, _pixsize - 1, _thickness, 1)); + _left.setDevicePixelRatio(cRetinaFactor()); + _top = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize - 1, 0, 1, _thickness)); + _top.setDevicePixelRatio(cRetinaFactor()); + _right = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize * 2 - _thickness, _pixsize, _thickness, 1)); + _right.setDevicePixelRatio(cRetinaFactor()); + _bottom = App::pixmapFromImageInPlace(cornersImage.copy(_pixsize, _pixsize * 2 - _thickness, 1, _thickness)); + _bottom.setDevicePixelRatio(cRetinaFactor()); + + _corners = App::pixmapFromImageInPlace(std_::move(cornersImage)); + _corners.setDevicePixelRatio(cRetinaFactor()); +} + +void RectShadow::paint(Painter &p, const QRect &box, int shifty, Sides sides) { + if (!_size) return; + + int32 rshifty = shifty * cIntRetinaFactor(); + int32 count = _thickness, countsize = count / cIntRetinaFactor(), minus = _size - countsize + shifty; + bool left = (sides & Side::Left), top = (sides & Side::Top), right = (sides & Side::Right), bottom = (sides & Side::Bottom); + if (left && top) p.drawPixmap(box.left() - _size + minus, box.top() - _size + minus + shifty, _corners, 0, 0, _pixsize, _pixsize); + if (right && top) p.drawPixmap(box.left() + box.width() - minus, box.top() - _size + minus + shifty, _corners, _pixsize, 0, _pixsize, _pixsize); + if (right && bottom) p.drawPixmap(box.left() + box.width() - minus, box.top() + box.height() - minus + shifty, _corners, _pixsize, _pixsize, _pixsize, _pixsize); + if (left && bottom) p.drawPixmap(box.left() - _size + minus, box.top() + box.height() - minus + shifty, _corners, 0, _pixsize, _pixsize, _pixsize); + + bool wasSmooth = p.renderHints().testFlag(QPainter::SmoothPixmapTransform); + if (wasSmooth) p.setRenderHint(QPainter::SmoothPixmapTransform, false); + if (left) p.drawPixmap(box.left() - countsize + shifty, box.top() + (top ? minus : 0) + shifty, countsize - shifty, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _left, 0, 0, count - rshifty, 1); + if (top) p.drawPixmap(box.left() + (left ? minus : 0), box.top() - countsize + 2 * shifty, box.width() - (right ? minus : 0) - (left ? minus : 0), countsize - 2 * shifty, _top, 0, 0, 1, count - 2 * rshifty); + if (right) p.drawPixmap(box.left() + box.width(), box.top() + (top ? minus : 0) + shifty, countsize - shifty, box.height() - (bottom ? minus : 0) - (top ? minus : 0), _right, rshifty, 0, count - rshifty, 1); + if (bottom) p.drawPixmap(box.left() + (left ? minus : 0), box.top() + box.height(), box.width() - (right ? minus : 0) - (left ? minus : 0), countsize, _bottom, 0, 0, 1, count); + if (wasSmooth) p.setRenderHint(QPainter::SmoothPixmapTransform); +} + +style::margins RectShadow::getDimensions(int32 shifty) const { + if (!_size) return style::margins(0, 0, 0, 0); + + int d = _thickness / cIntRetinaFactor(); + return style::margins(d - shifty, d - 2 * shifty, d - shifty, d); +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/boxshadow.h b/Telegram/SourceFiles/ui/effects/rect_shadow.h similarity index 77% rename from Telegram/SourceFiles/ui/boxshadow.h rename to Telegram/SourceFiles/ui/effects/rect_shadow.h index 3eeb302926..6822046b9b 100644 --- a/Telegram/SourceFiles/ui/boxshadow.h +++ b/Telegram/SourceFiles/ui/effects/rect_shadow.h @@ -20,29 +20,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -class BoxShadow { -public: - - enum { - Left = 1, - Top = 2, - Right = 4, - Bottom = 8 - }; - - BoxShadow(const style::sprite &topLeft); - - void paint(QPainter &p, const QRect &box, int32 shifty, int32 flags = Left | Top | Right | Bottom); - style::margins getDimensions(int32 shifty) const; - -private: - - int32 _size, _pixsize; - QPixmap _corners, _left, _top, _right, _bottom; - QVector _colors; - -}; - namespace Ui { class RectShadow { @@ -62,7 +39,6 @@ public: style::margins getDimensions(int shifty) const; private: - int _size, _pixsize; int _thickness = 0; QPixmap _corners, _left, _top, _right, _bottom; @@ -70,4 +46,4 @@ private: }; Q_DECLARE_OPERATORS_FOR_FLAGS(RectShadow::Sides); -} // namespace Ui \ No newline at end of file +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/flatinput.cpp b/Telegram/SourceFiles/ui/flatinput.cpp index 8dbdb173ed..de441e418e 100644 --- a/Telegram/SourceFiles/ui/flatinput.cpp +++ b/Telegram/SourceFiles/ui/flatinput.cpp @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "ui/flatinput.h" +#include "ui/popupmenu.h" #include "mainwindow.h" #include "countryinput.h" #include "lang.h" @@ -734,7 +735,7 @@ void InputArea::paintEvent(QPaintEvent *e) { Painter p(this); QRect r(rect().intersected(e->rect())); - p.fillRect(r, st::white->b); + p.fillRect(r, st::white); if (_st.border) { p.fillRect(0, height() - _st.border, width(), _st.border, _st.borderFg->b); } diff --git a/Telegram/SourceFiles/ui/flatlabel.cpp b/Telegram/SourceFiles/ui/flatlabel.cpp index dc73d2b062..e4d0a7d8bc 100644 --- a/Telegram/SourceFiles/ui/flatlabel.cpp +++ b/Telegram/SourceFiles/ui/flatlabel.cpp @@ -19,8 +19,9 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" - #include "ui/flatlabel.h" + +#include "ui/popupmenu.h" #include "mainwindow.h" #include "lang.h" diff --git a/Telegram/SourceFiles/ui/flatlabel.h b/Telegram/SourceFiles/ui/flatlabel.h index 912144c11f..b84d775e79 100644 --- a/Telegram/SourceFiles/ui/flatlabel.h +++ b/Telegram/SourceFiles/ui/flatlabel.h @@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +class PopupMenu; + class FlatLabel : public TWidget, public ClickHandlerHost { Q_OBJECT diff --git a/Telegram/SourceFiles/ui/flattextarea.cpp b/Telegram/SourceFiles/ui/flattextarea.cpp index 1aae737710..c6230c438a 100644 --- a/Telegram/SourceFiles/ui/flattextarea.cpp +++ b/Telegram/SourceFiles/ui/flattextarea.cpp @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "flattextarea.h" +#include "ui/popupmenu.h" #include "mainwindow.h" QByteArray FlatTextarea::serializeTagsList(const TagList &tags) { diff --git a/Telegram/SourceFiles/ui/inner_dropdown.h b/Telegram/SourceFiles/ui/inner_dropdown.h index 56f28caecb..2115679a4d 100644 --- a/Telegram/SourceFiles/ui/inner_dropdown.h +++ b/Telegram/SourceFiles/ui/inner_dropdown.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "ui/boxshadow.h" +#include "ui/effects/rect_shadow.h" class ScrollArea; diff --git a/Telegram/SourceFiles/ui/popupmenu.cpp b/Telegram/SourceFiles/ui/popupmenu.cpp index 2bbf658904..e6649b6293 100644 --- a/Telegram/SourceFiles/ui/popupmenu.cpp +++ b/Telegram/SourceFiles/ui/popupmenu.cpp @@ -25,43 +25,27 @@ #include "lang.h" -PopupMenu::PopupMenu(const style::PopupMenu &st) : TWidget(0) +PopupMenu::PopupMenu(const style::PopupMenu &st) : TWidget(nullptr) , _st(st) -, _menu(0) -, _parent(0) , _itemHeight(_st.itemPadding.top() + _st.itemFont->height + _st.itemPadding.bottom()) , _separatorHeight(_st.separatorPadding.top() + _st.separatorWidth + _st.separatorPadding.bottom()) -, _mouseSelection(false) , _shadow(_st.shadow) -, _selected(-1) -, _childMenuIndex(-1) , a_opacity(1) -, _a_hide(animation(this, &PopupMenu::step_hide)) -, _deleteOnHide(true) -, _triggering(false) -, _deleteLater(false) { +, _a_hide(animation(this, &PopupMenu::step_hide)) { init(); } PopupMenu::PopupMenu(QMenu *menu, const style::PopupMenu &st) : TWidget(0) , _st(st) , _menu(menu) -, _parent(0) , _itemHeight(_st.itemPadding.top() + _st.itemFont->height + _st.itemPadding.bottom()) , _separatorHeight(_st.separatorPadding.top() + _st.separatorWidth + _st.separatorPadding.bottom()) -, _mouseSelection(false) , _shadow(_st.shadow) -, _selected(-1) -, _childMenuIndex(-1) , a_opacity(1) -, _a_hide(animation(this, &PopupMenu::step_hide)) -, _deleteOnHide(true) -, _triggering(false) -, _deleteLater(false) { +, _a_hide(animation(this, &PopupMenu::step_hide)) { init(); - QList actions(menu->actions()); - for (int32 i = 0, l = actions.size(); i < l; ++i) { - addAction(actions.at(i)); + for (auto action : menu->actions()) { + addAction(action); } } @@ -117,7 +101,7 @@ int32 PopupMenu::processAction(QAction *a, int32 index, int32 w) { int32 textw = _st.itemFont->width(texts.at(0)); int32 goodw = _padding.left() + _st.itemPadding.left() + textw + _st.itemPadding.right() + _padding.right(); if (_menus.at(index)) { - goodw += _st.itemPadding.left() + _st.arrow.pxWidth(); + goodw += _st.itemPadding.left() + _st.arrow.width(); } else if (texts.size() > 1) { goodw += _st.itemPadding.left() + _st.itemFont->width(texts.at(1)); } @@ -212,7 +196,7 @@ void PopupMenu::paintEvent(QPaintEvent *e) { p.setPen(selected ? _st.itemFgOver : (enabled ? _st.itemFg : _st.itemFgDisabled)); p.drawTextLeft(_st.itemPadding.left(), _st.itemPadding.top(), _inner.width(), _texts.at(i)); if (_menus.at(i)) { - p.drawSpriteRight(_st.itemPadding.right(), (_itemHeight - _st.arrow.pxHeight()) / 2, _inner.width(), _st.arrow); + _st.arrow.paint(p, _inner.width() - _st.itemPadding.right() - _st.arrow.width(), (_itemHeight - _st.arrow.height()) / 2, _inner.width()); } else if (!_shortcutTexts.at(i).isEmpty()) { p.setPen(selected ? _st.itemFgShortcutOver : (enabled ? _st.itemFgShortcut : _st.itemFgShortcutDisabled)); p.drawTextRight(_st.itemPadding.right(), _st.itemPadding.top(), _inner.width(), _shortcutTexts.at(i)); diff --git a/Telegram/SourceFiles/ui/popupmenu.h b/Telegram/SourceFiles/ui/popupmenu.h index ccc1e8cfb8..aa4dc29e62 100644 --- a/Telegram/SourceFiles/ui/popupmenu.h +++ b/Telegram/SourceFiles/ui/popupmenu.h @@ -18,12 +18,12 @@ #pragma once #include "ui/text/text.h" +#include "ui/effects/rect_shadow.h" class PopupMenu : public TWidget { Q_OBJECT public: - PopupMenu(const style::PopupMenu &st = st::defaultPopupMenu); PopupMenu(QMenu *menu, const style::PopupMenu &st = st::defaultPopupMenu); QAction *addAction(const QString &text, const QObject *receiver, const char* member); @@ -41,23 +41,20 @@ public: ~PopupMenu(); protected: - - void resizeEvent(QResizeEvent *e); - void paintEvent(QPaintEvent *e); - void keyPressEvent(QKeyEvent *e); - void mouseMoveEvent(QMouseEvent *e); - void mousePressEvent(QMouseEvent *e); - void leaveEvent(QEvent *e); - void enterEvent(QEvent *e); - void focusOutEvent(QFocusEvent *e); - void hideEvent(QHideEvent *e); + void resizeEvent(QResizeEvent *e) override; + void paintEvent(QPaintEvent *e) override; + void keyPressEvent(QKeyEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void leaveEvent(QEvent *e) override; + void enterEvent(QEvent *e) override; + void focusOutEvent(QFocusEvent *e) override; + void hideEvent(QHideEvent *e) override; public slots: - void actionChanged(); private: - void updateSelected(); void childHiding(PopupMenu *child); @@ -85,10 +82,10 @@ private: typedef QVector PopupMenus; - QMenu *_menu; + QMenu *_menu = nullptr; Actions _actions; PopupMenus _menus; - PopupMenu *_parent; + PopupMenu *_parent = nullptr; QStringList _texts, _shortcutTexts; int32 _itemHeight, _separatorHeight; @@ -96,16 +93,19 @@ private: style::margins _padding; QPoint _mouse; - bool _mouseSelection; + bool _mouseSelection = false; - BoxShadow _shadow; - int32 _selected, _childMenuIndex; + Ui::RectShadow _shadow; + int _selected = -1; + int _childMenuIndex = -1; QPixmap _cache; anim::fvalue a_opacity; Animation _a_hide; - bool _deleteOnHide, _triggering, _deleteLater; + bool _deleteOnHide = true; + bool _triggering = false; + bool _deleteLater = false; }; @@ -123,7 +123,6 @@ class PopupTooltip : public TWidget { Q_OBJECT public: - bool eventFilter(QObject *o, QEvent *e); static void Show(int32 delay, const AbstractTooltipShower *shower); @@ -132,18 +131,15 @@ public: ~PopupTooltip(); public slots: - void onShow(); void onWndActiveChanged(); void onHideByLeave(); protected: - void paintEvent(QPaintEvent *e); void hideEvent(QHideEvent *e); private: - PopupTooltip(); void popup(const QPoint &p, const QString &text, const style::Tooltip *st); diff --git a/Telegram/SourceFiles/ui/style/style_core_icon.cpp b/Telegram/SourceFiles/ui/style/style_core_icon.cpp index 95445eb1b5..3eb35a2b9f 100644 --- a/Telegram/SourceFiles/ui/style/style_core_icon.cpp +++ b/Telegram/SourceFiles/ui/style/style_core_icon.cpp @@ -32,8 +32,11 @@ uint32 colorKey(const QColor &c) { using IconPixmaps = QMap, QPixmap>; NeverFreedPointer iconPixmaps; -int pxAdjust(int value, int scale) { - return qRound((value * scale) / 4. - 0.01); +inline int pxAdjust(int value, int scale) { + if (value < 0) { + return -pxAdjust(-value, scale); + } + return qFloor((value * scale / 4.) + 0.1); } QPixmap createIconPixmap(const IconMask *mask, const Color &color) { diff --git a/Telegram/SourceFiles/ui/toast/toast_manager.h b/Telegram/SourceFiles/ui/toast/toast_manager.h index 28419cf720..e8e42f9f8a 100644 --- a/Telegram/SourceFiles/ui/toast/toast_manager.h +++ b/Telegram/SourceFiles/ui/toast/toast_manager.h @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "ui/toast/toast.h" +#include "core/single_timer.h" namespace Ui { namespace Toast { diff --git a/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp b/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp new file mode 100644 index 0000000000..b572e5c128 --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp @@ -0,0 +1,167 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "ui/widgets/discrete_slider.h" + +#include "styles/style_widgets.h" + +namespace Ui { + +DiscreteSlider::DiscreteSlider(QWidget *parent) : TWidget(parent) +, _a_left(animation(this, &DiscreteSlider::step_left)) { + setCursor(style::cur_pointer); +} + +void DiscreteSlider::setSectionActivatedCallback(SectionActivatedCallback &&callback) { + _callback = std_::move(callback); +} + +void DiscreteSlider::setActiveSection(int index) { + setSelectedSection(index); + if (_activeIndex != index) { + _activeIndex = index; + if (_callback) { + _callback(); + } + } +} + +void DiscreteSlider::setActiveSectionFast(int index) { + setActiveSection(index); + a_left.finish(); + _a_left.stop(); + update(); +} + +void DiscreteSlider::addSection(const QString &label) { + auto section = Section(label); + _sections.push_back(section); +} + +void DiscreteSlider::resizeSections(int newWidth) { + auto count = _sections.size(); + if (!count) return; + + auto skips = count - 1; + auto sectionsWidth = newWidth - skips * st::discreteSliderSkip; + auto sectionWidth = sectionsWidth / float64(count); + auto x = 0.; + for (int i = 0; i != count; ++i) { + auto §ion = _sections[i]; + auto skip = i * st::discreteSliderThickness; + section.left = qFloor(x) + skip; + x += sectionWidth; + section.width = qRound(x) - (section.left - skip); + } + a_left = anim::ivalue(_sections[_activeIndex].left, _sections[_activeIndex].left); + _a_left.stop(); +} + +void DiscreteSlider::mousePressEvent(QMouseEvent *e) { + setSelectedSection(getIndexFromPosition(e->pos())); + _pressed = true; +} + +void DiscreteSlider::mouseMoveEvent(QMouseEvent *e) { + if (!_pressed) return; + setSelectedSection(getIndexFromPosition(e->pos())); +} + +void DiscreteSlider::mouseReleaseEvent(QMouseEvent *e) { + if (!_pressed) return; + _pressed = false; + setActiveSection(getIndexFromPosition(e->pos())); +} + +void DiscreteSlider::setSelectedSection(int index) { + if (index < 0) return; + + if (_selected != index) { + _selected = index; + a_left.start(_sections[_selected].left); + _a_left.start(); + } +} + +void DiscreteSlider::paintEvent(QPaintEvent *e) { + Painter p(this); + + int activeLeft = a_left.current(); + + p.setFont(st::discreteSliderLabelFont); + p.setPen(st::discreteSliderLabelFg); + for (int i = 0, count = _sections.size(); i != count; ++i) { + auto §ion = _sections.at(i); + auto from = section.left, tofill = section.width; + if (activeLeft > from) { + auto fill = qMin(tofill, activeLeft - from); + p.fillRect(myrtlrect(from, st::discreteSliderTop, fill, st::discreteSliderThickness), st::discreteSliderInactiveFg); + from += fill; + tofill -= fill; + } + if (activeLeft + section.width > from) { + if (auto fill = qMin(tofill, activeLeft + section.width - from)) { + p.fillRect(myrtlrect(from, st::discreteSliderTop, fill, st::discreteSliderThickness), st::discreteSliderActiveFg); + from += fill; + tofill -= fill; + } + } + if (tofill) { + p.fillRect(myrtlrect(from, st::discreteSliderTop, tofill, st::discreteSliderThickness), st::discreteSliderInactiveFg); + } + p.drawTextLeft(section.left + (section.width - section.labelWidth) / 2, st::discreteSliderLabelTop, width(), section.label, section.labelWidth); + } +} + +int DiscreteSlider::resizeGetHeight(int newWidth) { + resizeSections(newWidth); + return st::discreteSliderHeight; +} + +int DiscreteSlider::getIndexFromPosition(QPoint pos) { + int count = _sections.size(); + for (int i = 0; i != count; ++i) { + if (_sections[i].left + _sections[i].width > pos.x()) { + return i; + } + } + return count - 1; +} + +void DiscreteSlider::step_left(float64 ms, bool timer) { + auto dt = ms / st::discreteSliderDuration; + if (dt >= 1) { + a_left.finish(); + _a_left.stop(); + } else { + a_left.update(dt, anim::linear); + } + if (timer) { + update(); + } +} + +DiscreteSlider::Section::Section(const QString &label) +: label(label) +, labelWidth(st::discreteSliderLabelFont->width(label)) { +} + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/discrete_slider.h b/Telegram/SourceFiles/ui/widgets/discrete_slider.h new file mode 100644 index 0000000000..51c3bc1ff6 --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/discrete_slider.h @@ -0,0 +1,73 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Ui { + +class DiscreteSlider : public TWidget { +public: + DiscreteSlider(QWidget *parent); + + void addSection(const QString &label); + + int activeSection() const { + return _activeIndex; + } + void setActiveSection(int index); + void setActiveSectionFast(int index); + + using SectionActivatedCallback = base::lambda_unique; + void setSectionActivatedCallback(SectionActivatedCallback &&callback); + +protected: + void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + + int resizeGetHeight(int newWidth) override; + +private: + void resizeSections(int newWidth); + int getIndexFromPosition(QPoint pos); + void setSelectedSection(int index); + void step_left(float64 ms, bool timer); + + struct Section { + Section(const QString &label); + + int left, width; + QString label; + int labelWidth; + }; + QList
_sections; + int _activeIndex = 0; + + SectionActivatedCallback _callback; + + bool _pressed = false; + int _selected = 0; + anim::ivalue a_left = { 0 }; + Animation _a_left; + +}; + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style index a37ff09a35..8b6973705d 100644 --- a/Telegram/SourceFiles/ui/widgets/widgets.style +++ b/Telegram/SourceFiles/ui/widgets/widgets.style @@ -44,3 +44,14 @@ MediaSlider { } widgetSlideDuration: 200; + +discreteSliderHeight: 39px; +discreteSliderTop: 5px; +discreteSliderSkip: 3px; +discreteSliderThickness: 3px; +discreteSliderActiveFg: #4bb5e7; +discreteSliderInactiveFg: #e1eaef; +discreteSliderLabelTop: 17px; +discreteSliderLabelFont: normalFont; +discreteSliderLabelFg: #1485c2; +discreteSliderDuration: 200; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp new file mode 100644 index 0000000000..03b88ae1c3 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -0,0 +1,110 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "window/notifications_manager.h" + +#include "platform/platform_notifications_manager.h" +#include "window/notifications_manager_default.h" +#include "lang.h" +#include "mainwindow.h" +#include "mainwidget.h" + +namespace Window { +namespace Notifications { + +void start() { + Default::start(); + Platform::Notifications::start(); +} + +Manager *manager() { + if (auto result = Platform::Notifications::manager()) { + return result; + } + return Default::manager(); +} + +void finish() { + Platform::Notifications::finish(); + Default::finish(); +} + +Manager::DisplayOptions Manager::getNotificationOptions(HistoryItem *item) { + auto hideEverything = (App::passcoded() || Global::ScreenIsLocked()); + + DisplayOptions result; + result.hideNameAndPhoto = hideEverything || (Global::NotifyView() > dbinvShowName); + result.hideMessageText = hideEverything || (Global::NotifyView() > dbinvShowPreview); + result.hideReplyButton = result.hideMessageText || !item || !item->history()->peer->canWrite(); + return result; +} + +void Manager::notificationActivated(PeerId peerId, MsgId msgId) { + onBeforeNotificationActivated(peerId, msgId); + if (auto window = App::wnd()) { + auto history = App::history(peerId); + window->showFromTray(); + if (App::passcoded()) { + window->setInnerFocus(); + window->notifyClear(); + } else { + auto tomsg = !history->peer->isUser() && (msgId > 0); + if (tomsg) { + auto item = App::histItemById(peerToChannel(peerId), msgId); + if (!item || !item->mentionsMe()) { + tomsg = false; + } + } + Ui::showPeerHistory(history, tomsg ? msgId : ShowAtUnreadMsgId); + window->notifyClear(history); + } + } + onAfterNotificationActivated(peerId, msgId); +} + +void Manager::notificationReplied(PeerId peerId, MsgId msgId, const QString &reply) { + if (!peerId) return; + + auto history = App::history(peerId); + + MainWidget::MessageToSend message; + message.history = history; + message.textWithTags = { reply, TextWithTags::Tags() }; + message.replyTo = (msgId > 0 && !history->peer->isUser()) ? msgId : 0; + message.silent = false; + message.clearDraft = false; + if (auto main = App::main()) { + main->sendMessage(message); + } +} + +void NativeManager::doShowNotification(HistoryItem *item, int forwardedCount) { + auto options = getNotificationOptions(item); + + QString title = options.hideNameAndPhoto ? qsl("Telegram Desktop") : item->history()->peer->name; + QString subtitle = options.hideNameAndPhoto ? QString() : item->notificationHeader(); + QString text = options.hideMessageText ? lang(lng_notification_preview) : (forwardedCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, forwardedCount)); + + doShowNativeNotification(item->history()->peer, item->id, title, subtitle, text, options.hideNameAndPhoto, options.hideReplyButton); +} + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h new file mode 100644 index 0000000000..421d4d6c24 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -0,0 +1,96 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Window { +namespace Notifications { + +class Manager; + +void start(); +Manager *manager(); +void finish(); + +class Manager { +public: + void showNotification(HistoryItem *item, int forwardedCount) { + doShowNotification(item, forwardedCount); + } + void updateAll() { + doUpdateAll(); + } + void clearAll() { + doClearAll(); + } + void clearAllFast() { + doClearAllFast(); + } + void clearFromItem(HistoryItem *item) { + doClearFromItem(item); + } + void clearFromHistory(History *history) { + doClearFromHistory(history); + } + + void notificationActivated(PeerId peerId, MsgId msgId); + void notificationReplied(PeerId peerId, MsgId msgId, const QString &reply); + + struct DisplayOptions { + bool hideNameAndPhoto; + bool hideMessageText; + bool hideReplyButton; + }; + static DisplayOptions getNotificationOptions(HistoryItem *item); + + virtual ~Manager() = default; + +protected: + virtual void doUpdateAll() = 0; + virtual void doShowNotification(HistoryItem *item, int forwardedCount) = 0; + virtual void doClearAll() = 0; + virtual void doClearAllFast() = 0; + virtual void doClearFromItem(HistoryItem *item) = 0; + virtual void doClearFromHistory(History *history) = 0; + virtual void onBeforeNotificationActivated(PeerId peerId, MsgId msgId) { + } + virtual void onAfterNotificationActivated(PeerId peerId, MsgId msgId) { + } + +}; + +class NativeManager : public Manager { +protected: + void doUpdateAll() override { + doClearAllFast(); + } + void doClearAll() override { + doClearAllFast(); + } + void doClearFromItem(HistoryItem *item) override { + } + void doShowNotification(HistoryItem *item, int forwardedCount) override; + + virtual void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) = 0; + +}; + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp new file mode 100644 index 0000000000..e9c2e65573 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -0,0 +1,909 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "window/notifications_manager_default.h" + +#include "platform/platform_notifications_manager.h" +#include "mainwindow.h" +#include "lang.h" +#include "ui/buttons/icon_button.h" +#include "dialogs/dialogs_layout.h" +#include "styles/style_dialogs.h" +#include "styles/style_window.h" + +namespace Window { +namespace Notifications { +namespace Default { +namespace { + +NeverFreedPointer ManagerInstance; + +int notificationMaxHeight() { + return st::notifyMinHeight + st::notifyReplyArea.heightMax + st::notifyBorderWidth; +} + +QPoint notificationStartPosition() { + auto r = psDesktopRect(); + auto isLeft = Notify::IsLeftCorner(Global::NotificationsCorner()); + auto isTop = Notify::IsTopCorner(Global::NotificationsCorner()); + auto x = (isLeft == rtl()) ? (r.x() + r.width() - st::notifyWidth - st::notifyDeltaX) : (r.x() + st::notifyDeltaX); + auto y = isTop ? r.y() : (r.y() + r.height()); + return QPoint(x, y); +} + +internal::Widget::Direction notificationShiftDirection() { + auto isTop = Notify::IsTopCorner(Global::NotificationsCorner()); + return isTop ? internal::Widget::Direction::Down : internal::Widget::Direction::Up; +} + +} // namespace + +void start() { + ManagerInstance.makeIfNull(); +} + +Manager *manager() { + return ManagerInstance.data(); +} + +void finish() { + ManagerInstance.clear(); +} + +Manager::Manager() { + subscribe(FileDownload::ImageLoaded(), [this] { + for_const (auto notification, _notifications) { + notification->updatePeerPhoto(); + } + }); + subscribe(Global::RefNotifySettingsChanged(), [this](const Notify::ChangeType &change) { + settingsChanged(change); + }); + _inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); }); +} + +bool Manager::hasReplyingNotification() const { + for_const (auto notification, _notifications) { + if (notification->isReplying()) { + return true; + } + } + return false; +} + +void Manager::settingsChanged(const Notify::ChangeType &change) { + if (change == Notify::ChangeType::Corner) { + auto startPosition = notificationStartPosition(); + auto shiftDirection = notificationShiftDirection(); + for_const (auto notification, _notifications) { + notification->updatePosition(startPosition, shiftDirection); + } + if (_hideAll) { + _hideAll->updatePosition(startPosition, shiftDirection); + } + } else if (change == Notify::ChangeType::MaxCount) { + int allow = Global::NotificationsCount(); + for (int i = _notifications.size(); i != 0;) { + auto notification = _notifications[--i]; + if (notification->isUnlinked()) continue; + if (--allow < 0) { + notification->unlinkHistory(); + } + } + if (allow > 0) { + for (int i = 0; i != allow; ++i) { + showNextFromQueue(); + } + } + } else if (change == Notify::ChangeType::DemoIsShown) { + auto demoIsShown = Global::NotificationsDemoIsShown(); + _demoMasterOpacity.start([this] { demoMasterOpacityCallback(); }, demoIsShown ? 1. : 0., demoIsShown ? 0. : 1., st::notifyFastAnim); + } +} + +void Manager::demoMasterOpacityCallback() { + for_const (auto notification, _notifications) { + notification->updateOpacity(); + } + if (_hideAll) { + _hideAll->updateOpacity(); + } +} + +float64 Manager::demoMasterOpacity() const { + return _demoMasterOpacity.current(Global::NotificationsDemoIsShown() ? 0. : 1.); +} + +void Manager::checkLastInput() { + auto replying = hasReplyingNotification(); + auto waiting = false; + for_const (auto notification, _notifications) { + if (!notification->checkLastInput(replying)) { + waiting = true; + } + } + if (waiting) { + _inputCheckTimer.start(300); + } +} + +void Manager::startAllHiding() { + if (!hasReplyingNotification()) { + int notHidingCount = 0; + for_const (auto notification, _notifications) { + if (notification->isShowing()) { + ++notHidingCount; + } else { + notification->startHiding(); + } + } + notHidingCount += _queuedNotifications.size(); + if (_hideAll && notHidingCount < 2) { + _hideAll->startHiding(); + } + } +} + +void Manager::stopAllHiding() { + for_const (auto notification, _notifications) { + notification->stopHiding(); + } + if (_hideAll) { + _hideAll->stopHiding(); + } +} + +void Manager::showNextFromQueue() { + if (!_queuedNotifications.isEmpty()) { + int count = Global::NotificationsCount(); + for_const (auto notification, _notifications) { + if (notification->isUnlinked()) continue; + --count; + } + if (count > 0) { + auto startPosition = notificationStartPosition(); + auto startShift = 0; + auto shiftDirection = notificationShiftDirection(); + do { + auto queued = _queuedNotifications.front(); + _queuedNotifications.pop_front(); + + auto notification = std_::make_unique( + queued.history, + queued.peer, + queued.author, + queued.item, + queued.forwardedCount, + startPosition, startShift, shiftDirection); + Platform::Notifications::defaultNotificationShown(notification.get()); + _notifications.push_back(notification.release()); + --count; + } while (count > 0 && !_queuedNotifications.isEmpty()); + + _positionsOutdated = true; + checkLastInput(); + } + } + if (_positionsOutdated) { + moveWidgets(); + } +} + +void Manager::moveWidgets() { + auto shift = st::notifyDeltaY; + int lastShift = 0, lastShiftCurrent = 0, count = 0; + for (int i = _notifications.size(); i != 0;) { + auto notification = _notifications[--i]; + if (notification->isUnlinked()) continue; + + notification->changeShift(shift); + shift += notification->height() + st::notifyDeltaY; + + lastShiftCurrent = notification->currentShift(); + lastShift = shift; + + ++count; + } + + if (count > 1 || !_queuedNotifications.isEmpty()) { + auto deltaY = st::notifyHideAll.height + st::notifyDeltaY; + if (!_hideAll) { + _hideAll = new HideAllButton(notificationStartPosition(), lastShiftCurrent, notificationShiftDirection()); + } + _hideAll->changeShift(lastShift); + _hideAll->stopHiding(); + } else if (_hideAll) { + _hideAll->startHidingFast(); + } +} + +void Manager::changeNotificationHeight(Notification *notification, int newHeight) { + auto deltaHeight = newHeight - notification->height(); + if (!deltaHeight) return; + + notification->addToHeight(deltaHeight); + auto index = _notifications.indexOf(notification); + if (index > 0) { + for (int i = 0; i != index; ++i) { + auto notification = _notifications[i]; + if (notification->isUnlinked()) continue; + + notification->addToShift(deltaHeight); + } + } + if (_hideAll) { + _hideAll->addToShift(deltaHeight); + } +} + +void Manager::unlinkFromShown(Notification *remove) { + if (remove) { + if (remove->unlinkHistory()) { + _positionsOutdated = true; + } + } + showNextFromQueue(); +} + +void Manager::removeFromShown(Notification *remove) { + if (remove) { + auto index = _notifications.indexOf(remove); + if (index >= 0) { + _notifications.removeAt(index); + _positionsOutdated = true; + } + } + showNextFromQueue(); +} + +void Manager::removeHideAll(HideAllButton *remove) { + if (remove == _hideAll) { + _hideAll = nullptr; + } +} +void Manager::doShowNotification(HistoryItem *item, int forwardedCount) { + _queuedNotifications.push_back(QueuedNotification(item, forwardedCount)); + showNextFromQueue(); +} + +void Manager::doClearAll() { + _queuedNotifications.clear(); + for_const (auto notification, _notifications) { + notification->unlinkHistory(); + } + showNextFromQueue(); +} + +void Manager::doClearAllFast() { + _queuedNotifications.clear(); + auto notifications = base::take(_notifications); + for_const (auto notification, notifications) { + delete notification; + } + delete base::take(_hideAll); +} + +void Manager::doClearFromHistory(History *history) { + for (auto i = _queuedNotifications.begin(); i != _queuedNotifications.cend();) { + if (i->history == history) { + i = _queuedNotifications.erase(i); + } else { + ++i; + } + } + for_const (auto notification, _notifications) { + if (notification->unlinkHistory(history)) { + _positionsOutdated = true; + } + } + showNextFromQueue(); +} + +void Manager::doClearFromItem(HistoryItem *item) { + for (auto i = 0, queuedCount = _queuedNotifications.size(); i != queuedCount; ++i) { + if (_queuedNotifications[i].item == item) { + _queuedNotifications.removeAt(i); + break; + } + } + for_const (auto notification, _notifications) { + // Calls unlinkFromShown() -> showNextFromQueue() + notification->itemRemoved(item); + } +} + +void Manager::doUpdateAll() { + for_const (auto notification, _notifications) { + notification->updateNotifyDisplay(); + } +} + +Manager::~Manager() { + clearAllFast(); +} + +namespace internal { + +Widget::Widget(QPoint startPosition, int shift, Direction shiftDirection) : TWidget(nullptr) +, _opacityDuration(st::notifyFastAnim) +, a_opacity(0, 1) +, a_func(anim::linear) +, _a_opacity(animation(this, &Widget::step_opacity)) +, _startPosition(startPosition) +, _direction(shiftDirection) +, a_shift(shift) +, _a_shift(animation(this, &Widget::step_shift)) { + setWindowOpacity(0.); + + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint); + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_MacAlwaysShowToolWindow); + + _a_opacity.start(); +} + +void Widget::destroyDelayed() { + hide(); + if (_deleted) return; + _deleted = true; + + // Ubuntu has a lag if deleteLater() called immediately. +#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64 + QTimer::singleShot(1000, [this] { delete this; }); +#else // Q_OS_LINUX32 || Q_OS_LINUX64 + deleteLater(); +#endif // Q_OS_LINUX32 || Q_OS_LINUX64 +} + +void Widget::step_opacity(float64 ms, bool timer) { + float64 dt = ms / float64(_opacityDuration); + if (dt >= 1) { + a_opacity.finish(); + _a_opacity.stop(); + if (_hiding) { + destroyDelayed(); + } + } else { + a_opacity.update(dt, a_func); + } + updateOpacity(); + update(); +} + +void Widget::step_shift(float64 ms, bool timer) { + float64 dt = ms / float64(st::notifyFastAnim); + if (dt >= 1) { + a_shift.finish(); + } else { + a_shift.update(dt, anim::linear); + } + moveByShift(); +} + +void Widget::hideSlow() { + hideAnimated(st::notifySlowHide, st::notifySlowHideFunc); +} + +void Widget::hideFast() { + hideAnimated(st::notifyFastAnim, anim::linear); +} + +void Widget::hideStop() { + if (_hiding) { + _opacityDuration = st::notifyFastAnim; + a_func = anim::linear; + a_opacity.start(1); + _hiding = false; + _a_opacity.start(); + } +} + +void Widget::hideAnimated(float64 duration, anim::transition func) { + _opacityDuration = duration; + a_func = func; + a_opacity.start(0); + _hiding = true; + _a_opacity.start(); +} + +void Widget::updateOpacity() { + if (auto manager = ManagerInstance.data()) { + setWindowOpacity(a_opacity.current() * manager->demoMasterOpacity()); + } +} + +void Widget::changeShift(int top) { + a_shift.start(top); + _a_shift.start(); +} + +void Widget::updatePosition(QPoint startPosition, Direction shiftDirection) { + _startPosition = startPosition; + _direction = shiftDirection; + moveByShift(); +} + +void Widget::addToHeight(int add) { + auto newHeight = height() + add; + auto newPosition = computePosition(newHeight); + updateGeometry(newPosition.x(), newPosition.y(), width(), newHeight); +} + +void Widget::updateGeometry(int x, int y, int width, int height) { + setGeometry(x, y, width, height); + update(); +} + +void Widget::addToShift(int add) { + a_shift.add(add); + moveByShift(); +} + +void Widget::moveByShift() { + move(computePosition(height())); +} + +QPoint Widget::computePosition(int height) const { + auto realShift = a_shift.current(); + if (_direction == Direction::Up) { + realShift = -realShift - height; + } + return QPoint(_startPosition.x(), _startPosition.y() + realShift); +} + +Background::Background(QWidget *parent) : TWidget(parent) { + setAttribute(Qt::WA_OpaquePaintEvent); +} + +void Background::paintEvent(QPaintEvent *e) { + Painter p(this); + + p.fillRect(rect(), st::notifyBg); + p.fillRect(0, 0, st::notifyBorderWidth, height(), st::notifyBorder); + p.fillRect(width() - st::notifyBorderWidth, 0, st::notifyBorderWidth, height(), st::notifyBorder); + p.fillRect(st::notifyBorderWidth, height() - st::notifyBorderWidth, width() - 2 * st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder); +} + +Notification::Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *msg, int forwardedCount, QPoint startPosition, int shift, Direction shiftDirection) : Widget(startPosition, shift, shiftDirection) +, _history(history) +, _peer(peer) +, _author(author) +, _item(msg) +, _forwardedCount(forwardedCount) +#if defined Q_OS_WIN && !defined Q_OS_WINRT +, _started(GetTickCount()) +#endif // Q_OS_WIN && !Q_OS_WINRT +, _close(this, st::notifyClose) +, _reply(this, lang(lng_notification_reply), st::defaultBoxButton) { + auto position = computePosition(st::notifyMinHeight); + updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight); + + _userpicLoaded = _peer ? _peer->userpicLoaded() : true; + updateNotifyDisplay(); + + _hideTimer.setSingleShot(true); + connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideByTimer())); + + _close->setClickedCallback([this] { + unlinkHistoryInManager(); + }); + _close->setAcceptBoth(true); + _close->moveToRight(st::notifyClosePos.x(), st::notifyClosePos.y()); + _close->show(); + + _reply->setClickedCallback([this] { + showReplyField(); + }); + _replyPadding = st::notifyMinHeight - st::notifyPhotoPos.y() - st::notifyPhotoSize; + _reply->moveToRight(_replyPadding, height() - _reply->height() - _replyPadding); + _reply->hide(); + + prepareActionsCache(); + + show(); +} + +void Notification::prepareActionsCache() { + auto replyCache = myGrab(_reply); + auto fadeWidth = st::notifyFadeRight.width(); + auto actionsTop = st::notifyTextTop + st::msgNameFont->height; + auto actionsCacheWidth = _reply->width() + _replyPadding + fadeWidth; + auto actionsCacheHeight = height() - actionsTop; + auto actionsCacheImg = QImage(actionsCacheWidth * cIntRetinaFactor(), actionsCacheHeight * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + actionsCacheImg.setDevicePixelRatio(cRetinaFactor()); + actionsCacheImg.fill(st::transparent->c); + { + Painter p(&actionsCacheImg); + st::notifyFadeRight.fill(p, rtlrect(0, 0, fadeWidth, actionsCacheHeight, actionsCacheWidth)); + p.fillRect(rtlrect(fadeWidth, 0, actionsCacheWidth - fadeWidth, actionsCacheHeight, actionsCacheWidth), st::notifyBg); + p.drawPixmapRight(_replyPadding, _reply->y() - actionsTop, actionsCacheWidth, replyCache); + } + _buttonsCache = App::pixmapFromImageInPlace(std_::move(actionsCacheImg)); +} + +bool Notification::checkLastInput(bool hasReplyingNotifications) { + if (!_waitingForInput) return true; + + auto wasUserInput = true; // TODO +#if defined Q_OS_WIN && !defined Q_OS_WINRT + LASTINPUTINFO lii; + lii.cbSize = sizeof(LASTINPUTINFO); + BOOL res = GetLastInputInfo(&lii); + wasUserInput = (!res || lii.dwTime >= _started); +#endif // Q_OS_WIN && !Q_OS_WINRT + if (wasUserInput) { + _waitingForInput = false; + if (!hasReplyingNotifications) { + _hideTimer.start(st::notifyWaitLongHide); + } + return true; + } + return false; +} + +void Notification::onReplyResize() { + changeHeight(st::notifyMinHeight + _replyArea->height() + st::notifyBorderWidth); +} + +void Notification::onReplySubmit(bool ctrlShiftEnter) { + sendReply(); +} + +void Notification::onReplyCancel() { + unlinkHistoryInManager(); +} + +void Notification::updateGeometry(int x, int y, int width, int height) { + if (height > st::notifyMinHeight) { + if (!_background) { + _background = new Background(this); + } + _background->setGeometry(0, st::notifyMinHeight, width, height - st::notifyMinHeight); + } else if (_background) { + _background.destroy(); + } + Widget::updateGeometry(x, y, width, height); +} + +void Notification::paintEvent(QPaintEvent *e) { + Painter p(this); + p.setClipRect(e->rect()); + p.drawPixmap(0, 0, _cache); + + auto buttonsLeft = st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft; + auto buttonsTop = st::notifyTextTop + st::msgNameFont->height; + if (a_actionsOpacity.animating(getms())) { + p.setOpacity(a_actionsOpacity.current()); + p.drawPixmapRight(0, buttonsTop, width(), _buttonsCache); + } else if (_actionsVisible) { + p.drawPixmapRight(0, buttonsTop, width(), _buttonsCache); + } +} + +void Notification::actionsOpacityCallback() { + update(); + if (!a_actionsOpacity.animating() && _actionsVisible) { + _reply->show(); + } +} + +void Notification::updateNotifyDisplay() { + if (!_history || !_peer || (!_item && _forwardedCount < 2)) return; + + auto options = Manager::getNotificationOptions(_item); + _hideReplyButton = options.hideReplyButton; + + int32 w = width(), h = height(); + QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); + if (cRetina()) img.setDevicePixelRatio(cRetinaFactor()); + img.fill(st::notifyBg->c); + + { + Painter p(&img); + p.fillRect(0, 0, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder); + p.fillRect(w - st::notifyBorderWidth, 0, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder); + p.fillRect(st::notifyBorderWidth, h - st::notifyBorderWidth, w - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder); + p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, h - st::notifyBorderWidth, st::notifyBorder); + + if (!options.hideNameAndPhoto) { + _history->peer->loadUserpic(true, true); + _history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); + } else { + static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + icon.setDevicePixelRatio(cRetinaFactor()); + p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), icon); + } + + int32 itemWidth = w - st::notifyPhotoPos.x() - st::notifyPhotoSize - st::notifyTextLeft - st::notifyClosePos.x() - st::notifyClose.width; + + QRect rectForName(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyTextTop, itemWidth, st::msgNameFont->height); + if (!options.hideNameAndPhoto) { + if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(_history->peer, false)) { + chatTypeIcon->paint(p, rectForName.topLeft(), w); + rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); + } + } + + if (!options.hideMessageText) { + const HistoryItem *textCachedFor = 0; + Text itemTextCache(itemWidth); + QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height); + if (_item) { + bool active = false; + _item->drawInDialog(p, r, active, textCachedFor, itemTextCache); + } else if (_forwardedCount > 1) { + p.setFont(st::dialogsTextFont); + if (_author) { + itemTextCache.setText(st::dialogsTextFont, _author->name); + p.setPen(st::dialogsTextFgService); + itemTextCache.drawElided(p, r.left(), r.top(), r.width(), st::dialogsTextFont->height); + r.setTop(r.top() + st::dialogsTextFont->height); + } + p.setPen(st::dialogsTextFg); + p.drawText(r.left(), r.top() + st::dialogsTextFont->ascent, lng_forward_messages(lt_count, _forwardedCount)); + } + } else { + static QString notifyText = st::dialogsTextFont->elided(lang(lng_notification_preview), itemWidth); + p.setFont(st::dialogsTextFont); + p.setPen(st::dialogsTextFgService); + p.drawText(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height + st::dialogsTextFont->ascent, notifyText); + } + + p.setPen(st::dialogsNameFg); + if (!options.hideNameAndPhoto) { + _history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + } else { + p.setFont(st::msgNameFont); + static QString notifyTitle = st::msgNameFont->elided(qsl("Telegram Desktop"), rectForName.width()); + p.drawText(rectForName.left(), rectForName.top() + st::msgNameFont->ascent, notifyTitle); + } + } + + _cache = App::pixmapFromImageInPlace(std_::move(img)); + if (!canReply()) { + toggleActionButtons(false); + } + update(); +} + +void Notification::updatePeerPhoto() { + if (_userpicLoaded || !_peer || !_peer->userpicLoaded()) { + return; + } + _userpicLoaded = true; + + auto img = _cache.toImage(); + { + Painter p(&img); + _peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); + } + _cache = App::pixmapFromImageInPlace(std_::move(img)); + update(); +} + +void Notification::itemRemoved(HistoryItem *deleted) { + if (_item && _item == deleted) { + _item = nullptr; + unlinkHistoryInManager(); + } +} + +bool Notification::canReply() const { + return !_hideReplyButton && (_item != nullptr) && !App::passcoded() && (Global::NotifyView() <= dbinvShowPreview); +} + +void Notification::unlinkHistoryInManager() { + if (auto manager = ManagerInstance.data()) { + manager->unlinkFromShown(this); + } +} + +void Notification::toggleActionButtons(bool visible) { + if (_actionsVisible != visible) { + _actionsVisible = visible; + a_actionsOpacity.start([this] { actionsOpacityCallback(); }, _actionsVisible ? 0. : 1., _actionsVisible ? 1. : 0., st::notifyActionsDuration); + _reply->hide(); + } +} + +void Notification::showReplyField() { + if (_replyArea) return; + stopHiding(); + + _background = new Background(this); + _background->setGeometry(0, st::notifyMinHeight, width(), st::notifySendReply.height + st::notifyBorderWidth); + _background->show(); + + _replyArea = new InputArea(this, st::notifyReplyArea, lang(lng_message_ph), QString()); + _replyArea->resize(width() - st::notifySendReply.width - 2 * st::notifyBorderWidth, st::notifySendReply.height); + _replyArea->moveToLeft(st::notifyBorderWidth, st::notifyMinHeight); + _replyArea->show(); + _replyArea->setFocus(); + _replyArea->setMaxLength(MaxMessageSize); + _replyArea->setCtrlEnterSubmit(CtrlEnterSubmitBoth); + connect(_replyArea, SIGNAL(resized()), this, SLOT(onReplyResize())); + connect(_replyArea, SIGNAL(submitted(bool)), this, SLOT(onReplySubmit(bool))); + connect(_replyArea, SIGNAL(cancelled()), this, SLOT(onReplyCancel())); + + _replySend = new Ui::IconButton(this, st::notifySendReply); + _replySend->moveToRight(st::notifyBorderWidth, st::notifyMinHeight); + _replySend->show(); + _replySend->setClickedCallback([this] { sendReply(); }); + + toggleActionButtons(false); + + onReplyResize(); + update(); +} + +void Notification::sendReply() { + if (!_history) return; + + if (auto manager = ManagerInstance.data()) { + auto peerId = _history->peer->id; + auto msgId = _item ? _item->id : ShowAtUnreadMsgId; + manager->notificationReplied(peerId, msgId, _replyArea->getLastText()); + + manager->startAllHiding(); + } +} + +void Notification::changeHeight(int newHeight) { + if (auto manager = ManagerInstance.data()) { + manager->changeNotificationHeight(this, newHeight); + } +} + +bool Notification::unlinkHistory(History *history) { + auto unlink = _history && (history == _history || !history); + if (unlink) { + hideFast(); + _history = nullptr; + _item = nullptr; + } + return unlink; +} + +void Notification::enterEvent(QEvent *e) { + if (!_history) return; + if (auto manager = ManagerInstance.data()) { + manager->stopAllHiding(); + } + if (!_replyArea && canReply()) { + toggleActionButtons(true); + } +} + +void Notification::leaveEvent(QEvent *e) { + if (!_history) return; + if (auto manager = ManagerInstance.data()) { + manager->startAllHiding(); + } + toggleActionButtons(false); +} + +void Notification::startHiding() { + if (!_history) return; + hideSlow(); +} + +void Notification::mousePressEvent(QMouseEvent *e) { + if (!_history) return; + + if (e->button() == Qt::RightButton) { + unlinkHistoryInManager(); + } else { + e->ignore(); + if (auto manager = ManagerInstance.data()) { + auto peerId = _history->peer->id; + auto msgId = _item ? _item->id : ShowAtUnreadMsgId; + manager->notificationActivated(peerId, msgId); + } + } +} + +void Notification::stopHiding() { + if (!_history) return; + _hideTimer.stop(); + Widget::hideStop(); +} + +void Notification::onHideByTimer() { + startHiding(); +} + +Notification::~Notification() { + if (auto manager = ManagerInstance.data()) { + manager->removeFromShown(this); + } +} + +HideAllButton::HideAllButton(QPoint startPosition, int shift, Direction shiftDirection) : Widget(startPosition, shift, shiftDirection) { + setCursor(style::cur_pointer); + + auto position = computePosition(st::notifyHideAll.height); + updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyHideAll.height); + hide(); + createWinId(); + + show(); +} + +void HideAllButton::startHiding() { + hideSlow(); +} + +void HideAllButton::startHidingFast() { + hideFast(); +} + +void HideAllButton::stopHiding() { + hideStop(); +} + +HideAllButton::~HideAllButton() { + if (auto manager = ManagerInstance.data()) { + manager->removeHideAll(this); + } +} + +void HideAllButton::enterEvent(QEvent *e) { + _mouseOver = true; + update(); +} + +void HideAllButton::leaveEvent(QEvent *e) { + _mouseOver = false; + update(); +} + +void HideAllButton::mousePressEvent(QMouseEvent *e) { + _mouseDown = true; +} + +void HideAllButton::mouseReleaseEvent(QMouseEvent *e) { + auto mouseDown = base::take(_mouseDown); + if (mouseDown && _mouseOver) { + if (auto manager = ManagerInstance.data()) { + manager->clearAll(); + } + } +} + +void HideAllButton::paintEvent(QPaintEvent *e) { + Painter p(this); + p.setClipRect(e->rect()); + + p.fillRect(rect(), _mouseOver ? st::notifyHideAll.textBgOver : st::notifyHideAll.textBg); + p.fillRect(0, 0, width(), st::notifyBorderWidth, st::notifyBorder); + p.fillRect(0, height() - st::notifyBorderWidth, width(), st::notifyBorderWidth, st::notifyBorder); + p.fillRect(0, st::notifyBorderWidth, st::notifyBorderWidth, height() - 2 * st::notifyBorderWidth, st::notifyBorder); + p.fillRect(width() - st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorderWidth, height() - 2 * st::notifyBorderWidth, st::notifyBorder); + + p.setFont(st::btnDefLink.font); + p.setPen(st::btnDefLink.color); + p.drawText(rect(), lang(lng_notification_hide_all), style::al_center); +} + +} // namespace internal +} // namespace Default +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h new file mode 100644 index 0000000000..0181d85e0a --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -0,0 +1,287 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/notifications_manager.h" +#include "core/single_timer.h" + +namespace Ui { +class IconButton; +} // namespace Ui + +namespace Window { +namespace Notifications { +namespace Default { +namespace internal { +class Widget; +class Notification; +class HideAllButton; +} // namespace internal + +class Manager; + +void start(); +Manager *manager(); +void finish(); + +class Manager : public Notifications::Manager, private base::Subscriber { +public: + Manager(); + + template + void enumerateNotifications(Method method) { + for_const (auto notification, _notifications) { + method(notification); + } + } + + ~Manager(); + +private: + friend class internal::Notification; + friend class internal::HideAllButton; + friend class internal::Widget; + using Notification = internal::Notification; + using HideAllButton = internal::HideAllButton; + + void doUpdateAll() override; + void doShowNotification(HistoryItem *item, int forwardedCount) override; + void doClearAll() override; + void doClearAllFast() override; + void doClearFromHistory(History *history) override; + void doClearFromItem(HistoryItem *item) override; + + void showNextFromQueue(); + void unlinkFromShown(Notification *remove); + void removeFromShown(Notification *remove); + void removeHideAll(HideAllButton *remove); + void startAllHiding(); + void stopAllHiding(); + void checkLastInput(); + + float64 demoMasterOpacity() const; + void demoMasterOpacityCallback(); + + void moveWidgets(); + void changeNotificationHeight(Notification *widget, int newHeight); + void settingsChanged(const Notify::ChangeType &change); + + bool hasReplyingNotification() const; + + using Notifications = QList; + Notifications _notifications; + + HideAllButton *_hideAll = nullptr; + + bool _positionsOutdated = false; + SingleTimer _inputCheckTimer; + + struct QueuedNotification { + QueuedNotification(HistoryItem *item, int forwardedCount) + : history(item->history()) + , peer(history->peer) + , author((item->hasFromName() && !item->isPost()) ? item->author() : nullptr) + , item((forwardedCount > 1) ? nullptr : item) + , forwardedCount(forwardedCount) { + } + + History *history; + PeerData *peer; + PeerData *author; + HistoryItem *item; + int forwardedCount; + }; + using QueuedNotifications = QList; + QueuedNotifications _queuedNotifications; + + FloatAnimation _demoMasterOpacity; + +}; + +namespace internal { + +class Widget : public TWidget { +public: + enum class Direction { + Up, + Down, + }; + Widget(QPoint startPosition, int shift, Direction shiftDirection); + + bool isShowing() const { + return _a_opacity.animating() && !_hiding; + } + + void updateOpacity(); + void changeShift(int top); + int currentShift() const { + return a_shift.current(); + } + void updatePosition(QPoint startPosition, Direction shiftDirection); + void addToHeight(int add); + void addToShift(int add); + +protected: + void hideSlow(); + void hideFast(); + void hideStop(); + QPoint computePosition(int height) const; + + virtual void updateGeometry(int x, int y, int width, int height); + +private: + void destroyDelayed(); + void moveByShift(); + void hideAnimated(float64 duration, anim::transition func); + void step_opacity(float64 ms, bool timer); + void step_shift(float64 ms, bool timer); + + bool _hiding = false; + bool _deleted = false; + float64 _opacityDuration; + anim::fvalue a_opacity; + anim::transition a_func; + Animation _a_opacity; + + QPoint _startPosition; + Direction _direction; + anim::ivalue a_shift; + Animation _a_shift; + +}; + +class Background : public TWidget { +public: + Background(QWidget *parent); + +protected: + void paintEvent(QPaintEvent *e) override; + +}; + +class Notification : public Widget { + Q_OBJECT + +public: + Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, QPoint startPosition, int shift, Direction shiftDirection); + + void startHiding(); + void stopHiding(); + + void updateNotifyDisplay(); + void updatePeerPhoto(); + + bool isUnlinked() const { + return !_history; + } + bool isReplying() const { + return (_replyArea != nullptr) && !isUnlinked(); + } + + // Called only by Manager. + void itemRemoved(HistoryItem *del); + bool unlinkHistory(History *history = nullptr); + bool checkLastInput(bool hasReplyingNotifications); + + ~Notification(); + +protected: + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + +private slots: + void onHideByTimer(); + void onReplyResize(); + void onReplySubmit(bool ctrlShiftEnter); + void onReplyCancel(); + +private: + bool canReply() const; + + void unlinkHistoryInManager(); + void toggleActionButtons(bool visible); + void prepareActionsCache(); + void showReplyField(); + void sendReply(); + void changeHeight(int newHeight); + void updateGeometry(int x, int y, int width, int height) override; + void actionsOpacityCallback(); + + QPixmap _cache; + + bool _hideReplyButton = false; + bool _actionsVisible = false; + FloatAnimation a_actionsOpacity; + QPixmap _buttonsCache; + +#if defined Q_OS_WIN && !defined Q_OS_WINRT + uint64 _started; +#endif // Q_OS_WIN && !Q_OS_WINRT + + History *_history; + PeerData *_peer; + PeerData *_author; + HistoryItem *_item; + int _forwardedCount; + ChildWidget _close; + ChildWidget _reply; + ChildWidget _background = { nullptr }; + ChildWidget _replyArea = { nullptr }; + ChildWidget _replySend = { nullptr }; + bool _waitingForInput = true; + + QTimer _hideTimer; + + int _replyPadding = 0; + + bool _userpicLoaded = false; + +}; + +class HideAllButton : public Widget { +public: + HideAllButton(QPoint startPosition, int shift, Direction shiftDirection); + + void startHiding(); + void startHidingFast(); + void stopHiding(); + + ~HideAllButton(); + +protected: + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void paintEvent(QPaintEvent *e) override; + +private: + bool _mouseOver = false; + bool _mouseDown = false; + +}; + +} // namespace internal +} // namespace Default +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_utilities.cpp b/Telegram/SourceFiles/window/notifications_utilities.cpp new file mode 100644 index 0000000000..2d48cdd4cb --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_utilities.cpp @@ -0,0 +1,117 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "window/notifications_utilities.h" + +#include "pspecific.h" +#include "mainwindow.h" +#include "styles/style_window.h" + +namespace Window { +namespace Notifications { +namespace { + +// Delete notify photo file after 1 minute of not using. +constexpr int kNotifyDeletePhotoAfterMs = 60000; + +} // namespace + +CachedUserpics::CachedUserpics() { + connect(&_clearTimer, SIGNAL(timeout()), this, SLOT(onClear())); + QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); +} + +QString CachedUserpics::get(const StorageKey &key, PeerData *peer) { + uint64 ms = getms(true); + auto i = _images.find(key); + if (i != _images.cend()) { + if (i->until) { + i->until = ms + kNotifyDeletePhotoAfterMs; + clearInMs(-kNotifyDeletePhotoAfterMs); + } + } else { + Image v; + if (key.first) { + v.until = ms + kNotifyDeletePhotoAfterMs; + clearInMs(-kNotifyDeletePhotoAfterMs); + } else { + v.until = 0; + } + v.path = cWorkingDir() + qsl("tdata/temp/") + QString::number(rand_value(), 16) + qsl(".png"); + if (key.first || key.second) { + peer->saveUserpic(v.path, st::notifyMacPhotoSize); + } else { + App::wnd()->iconLarge().save(v.path, "PNG"); + } + i = _images.insert(key, v); + _someSavedFlag = true; + } + return i->path; +} + +uint64 CachedUserpics::clear(uint64 ms) { + uint64 result = 0; + for (auto i = _images.begin(); i != _images.end();) { + if (!i->until) { + ++i; + continue; + } + if (i->until <= ms) { + QFile(i->path).remove(); + i = _images.erase(i); + } else { + if (!result) { + result = i->until; + } else { + accumulate_min(result, i->until); + } + ++i; + } + } + return result; +} + +void CachedUserpics::clearInMs(int ms) { + if (ms < 0) { + ms = -ms; + if (_clearTimer.isActive() && _clearTimer.remainingTime() <= ms) { + return; + } + } + _clearTimer.start(ms); +} + +void CachedUserpics::onClear() { + auto ms = getms(true); + auto minuntil = clear(ms); + if (minuntil) { + clearInMs(int(minuntil - ms)); + } +} + +CachedUserpics::~CachedUserpics() { + if (_someSavedFlag) { + psDeleteDir(cWorkingDir() + qsl("tdata/temp")); + } +} + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_utilities.h b/Telegram/SourceFiles/window/notifications_utilities.h new file mode 100644 index 0000000000..f5609210b2 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_utilities.h @@ -0,0 +1,58 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/notifications_manager.h" +#include "core/single_timer.h" + +namespace Window { +namespace Notifications { + +class CachedUserpics : public QObject { + Q_OBJECT + +public: + CachedUserpics(); + + QString get(const StorageKey &key, PeerData *peer); + + ~CachedUserpics(); + +private slots: + void onClear(); + +private: + void clearInMs(int ms); + uint64 clear(uint64 ms); + + struct Image { + uint64 until; + QString path; + }; + using Images = QMap; + Images _images; + bool _someSavedFlag = false; + SingleTimer _clearTimer; + +}; + +} // namesapce Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style new file mode 100644 index 0000000000..721d756c99 --- /dev/null +++ b/Telegram/SourceFiles/window/window.style @@ -0,0 +1,71 @@ +/* +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-2016 John Preston, https://desktop.telegram.org +*/ + +using "basic.style"; + +notifyBg: white; +notifyBorder: #f1f1f1; +notifyBorderWidth: 1px; +notifySlowHide: 4000; +notifyPhotoSize: 62px; +notifyMacPhotoSize: 64px; +notifyPhotoPos: point(9px, 9px); +notifyClosePos: point(1px, 2px); +notifyClose: iconedButton(simpleClose) { +} +notifyItemTop: 12px; +notifyTextLeft: 12px; +notifyTextTop: 7px; +notifySlowHideFunc: transition(easeInCirc); +notifyWaitLongHide: 3000; +notifyFastAnim: 150; +notifyWidth: 320px; +notifyMinHeight: 80px; +notifyDeltaX: 6px; +notifyDeltaY: 7px; +notifyActionsDuration: 200; + +notifyHideAll: RoundButton(defaultBoxButton) { +} + +notifyFadeRight: icon {{ "fade_horizontal_right", notifyBg }}; +notifyReplyArea: InputArea(defaultInputArea) { + font: normalFont; + textMargins: margins(8px, 8px, 8px, 6px); + heightMin: 36px; + heightMax: 72px; + border: 0px; + borderActive: 0px; + borderError: 0px; +} +notifySendReply: IconButton { + width: 36px; + height: 36px; + + opacity: 0.78; + overOpacity: 1.; + + icon: icon {{ "notification_send", windowActiveBg, point(3px, 9px) }}; + iconPosition: point(0px, 0px); + downIconPosition: point(0px, 1px); + + duration: notifyFastAnim; +} diff --git a/Telegram/build/deploy.sh b/Telegram/build/deploy.sh index 0ac8f307b1..911eabd5aa 100755 --- a/Telegram/build/deploy.sh +++ b/Telegram/build/deploy.sh @@ -181,20 +181,18 @@ fi if [ "$BuildTarget" == "linux" ] || [ "$BuildTarget" == "linux32" ] || [ "$BuildTarget" == "mac" ]; then if [ "$BuildTarget" != "mac" ] || [ "$DeployMac" == "1" ]; then - scp "$DeployPath/$UpdateFile" "tmaster:tdesktop/www/$RemoteFolder/" - scp "$DeployPath/$SetupFile" "tmaster:tdesktop/www/$RemoteFolder/" + rsync -av --progress "$DeployPath/$UpdateFile" "$DeployPath/$SetupFile" "tmaster:tdesktop/www/$RemoteFolder/" fi if [ "$BuildTarget" == "mac" ]; then if [ "$DeployMac32" == "1" ]; then - scp "$Mac32DeployPath/$Mac32UpdateFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/" - scp "$Mac32DeployPath/$Mac32SetupFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/" + rsync -av --progress "$Mac32DeployPath/$Mac32UpdateFile" "$Mac32DeployPath/$Mac32SetupFile" "tmaster:tdesktop/www/$Mac32RemoteFolder/" fi if [ "$DeployWin" == "1" ]; then - scp "$WinDeployPath/$WinUpdateFile" "tmaster:tdesktop/www/$WinRemoteFolder/" if [ "$BetaVersion" == "0" ]; then - scp "$WinDeployPath/$WinSetupFile" "tmaster:tdesktop/www/$WinRemoteFolder/" + rsync -av --progress "$WinDeployPath/$WinUpdateFile" "$WinDeployPath/$WinSetupFile" "$WinDeployPath/$WinPortableFile" "tmaster:tdesktop/www/$WinRemoteFolder/" + else + rsync -av --progress "$WinDeployPath/$WinUpdateFile" "$WinDeployPath/$WinPortableFile" "tmaster:tdesktop/www/$WinRemoteFolder/" fi - scp "$WinDeployPath/$WinPortableFile" "tmaster:tdesktop/www/$WinRemoteFolder/" fi if [ "$DeployMac" == "1" ]; then diff --git a/Telegram/build/version b/Telegram/build/version index 78b24b0d92..4b2feb611d 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10008 +AppVersion 10013 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.8 -AppVersionStr 0.10.8 -AlphaChannel 0 -BetaVersion 10008005 +AppVersionStrSmall 0.10.13 +AppVersionStr 0.10.13 +AlphaChannel 1 +BetaVersion 0 diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index b808171e06..a3322c09d5 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -41,6 +41,7 @@ '<(src_loc)/settings/settings.style', '<(src_loc)/stickers/stickers.style', '<(src_loc)/ui/widgets/widgets.style', + '<(src_loc)/window/window.style', ], 'langpacks': [ 'en', @@ -176,6 +177,8 @@ '<(src_loc)/boxes/languagebox.h', '<(src_loc)/boxes/localstoragebox.cpp', '<(src_loc)/boxes/localstoragebox.h', + '<(src_loc)/boxes/notifications_box.cpp', + '<(src_loc)/boxes/notifications_box.h', '<(src_loc)/boxes/passcodebox.cpp', '<(src_loc)/boxes/passcodebox.h', '<(src_loc)/boxes/photocropbox.cpp', @@ -205,6 +208,8 @@ '<(src_loc)/core/qthelp_url.h', '<(src_loc)/core/runtime_composer.cpp', '<(src_loc)/core/runtime_composer.h', + '<(src_loc)/core/single_timer.cpp', + '<(src_loc)/core/single_timer.h', '<(src_loc)/core/stl_subset.h', '<(src_loc)/core/utils.cpp', '<(src_loc)/core/utils.h', @@ -331,24 +336,35 @@ '<(src_loc)/pspecific_linux.h', '<(src_loc)/platform/linux/linux_gdk_helper.cpp', '<(src_loc)/platform/linux/linux_gdk_helper.h', + '<(src_loc)/platform/linux/linux_libnotify.cpp', + '<(src_loc)/platform/linux/linux_libnotify.h', '<(src_loc)/platform/linux/linux_libs.cpp', '<(src_loc)/platform/linux/linux_libs.h', '<(src_loc)/platform/linux/file_dialog_linux.cpp', '<(src_loc)/platform/linux/file_dialog_linux.h', '<(src_loc)/platform/linux/main_window_linux.cpp', '<(src_loc)/platform/linux/main_window_linux.h', + '<(src_loc)/platform/linux/notifications_manager_linux.cpp', + '<(src_loc)/platform/linux/notifications_manager_linux.h', + '<(src_loc)/platform/mac/mac_utilities.mm', + '<(src_loc)/platform/mac/mac_utilities.h', '<(src_loc)/platform/mac/main_window_mac.mm', '<(src_loc)/platform/mac/main_window_mac.h', + '<(src_loc)/platform/mac/notifications_manager_mac.mm', + '<(src_loc)/platform/mac/notifications_manager_mac.h', '<(src_loc)/platform/win/main_window_win.cpp', '<(src_loc)/platform/win/main_window_win.h', + '<(src_loc)/platform/win/notifications_manager_win.cpp', + '<(src_loc)/platform/win/notifications_manager_win.h', '<(src_loc)/platform/win/windows_app_user_model_id.cpp', '<(src_loc)/platform/win/windows_app_user_model_id.h', '<(src_loc)/platform/win/windows_dlls.cpp', '<(src_loc)/platform/win/windows_dlls.h', '<(src_loc)/platform/win/windows_event_filter.cpp', '<(src_loc)/platform/win/windows_event_filter.h', - '<(src_loc)/platform/win/windows_toasts.cpp', - '<(src_loc)/platform/win/windows_toasts.h', + '<(src_loc)/platform/platform_file_dialog.h', + '<(src_loc)/platform/platform_main_window.h', + '<(src_loc)/platform/platform_notifications_manager.h', '<(src_loc)/profile/profile_actions_widget.cpp', '<(src_loc)/profile/profile_actions_widget.h', '<(src_loc)/profile/profile_block_widget.cpp', @@ -425,6 +441,8 @@ '<(src_loc)/ui/effects/fade_animation.h', '<(src_loc)/ui/effects/radial_animation.cpp', '<(src_loc)/ui/effects/radial_animation.h', + '<(src_loc)/ui/effects/rect_shadow.cpp', + '<(src_loc)/ui/effects/rect_shadow.h', '<(src_loc)/ui/style/style_core.cpp', '<(src_loc)/ui/style/style_core.h', '<(src_loc)/ui/style/style_core_color.cpp', @@ -452,10 +470,10 @@ '<(src_loc)/ui/widgets/media_slider.cpp', '<(src_loc)/ui/widgets/media_slider.h', '<(src_loc)/ui/widgets/widget_slide_wrap.h', + '<(src_loc)/ui/widgets/discrete_slider.cpp', + '<(src_loc)/ui/widgets/discrete_slider.h', '<(src_loc)/ui/animation.cpp', '<(src_loc)/ui/animation.h', - '<(src_loc)/ui/boxshadow.cpp', - '<(src_loc)/ui/boxshadow.h', '<(src_loc)/ui/button.cpp', '<(src_loc)/ui/button.h', '<(src_loc)/ui/popupmenu.cpp', @@ -488,6 +506,12 @@ '<(src_loc)/window/chat_background.h', '<(src_loc)/window/main_window.cpp', '<(src_loc)/window/main_window.h', + '<(src_loc)/window/notifications_manager.cpp', + '<(src_loc)/window/notifications_manager.h', + '<(src_loc)/window/notifications_manager_default.cpp', + '<(src_loc)/window/notifications_manager_default.h', + '<(src_loc)/window/notifications_utilities.cpp', + '<(src_loc)/window/notifications_utilities.h', '<(src_loc)/window/section_widget.cpp', '<(src_loc)/window/section_widget.h', '<(src_loc)/window/slide_animation.cpp', @@ -510,12 +534,16 @@ '<(src_loc)/pspecific_linux.h', '<(src_loc)/platform/linux/linux_gdk_helper.cpp', '<(src_loc)/platform/linux/linux_gdk_helper.h', + '<(src_loc)/platform/linux/linux_libnotify.cpp', + '<(src_loc)/platform/linux/linux_libnotify.h', '<(src_loc)/platform/linux/linux_libs.cpp', '<(src_loc)/platform/linux/linux_libs.h', '<(src_loc)/platform/linux/file_dialog_linux.cpp', '<(src_loc)/platform/linux/file_dialog_linux.h', '<(src_loc)/platform/linux/main_window_linux.cpp', '<(src_loc)/platform/linux/main_window_linux.h', + '<(src_loc)/platform/linux/notifications_manager_linux.cpp', + '<(src_loc)/platform/linux/notifications_manager_linux.h', ], }], [ '"<(build_mac)" != "1"', { @@ -524,8 +552,12 @@ '<(src_loc)/pspecific_mac.h', '<(src_loc)/pspecific_mac_p.mm', '<(src_loc)/pspecific_mac_p.h', + '<(src_loc)/platform/mac/mac_utilities.mm', + '<(src_loc)/platform/mac/mac_utilities.h', '<(src_loc)/platform/mac/main_window_mac.mm', '<(src_loc)/platform/mac/main_window_mac.h', + '<(src_loc)/platform/mac/notifications_manager_mac.mm', + '<(src_loc)/platform/mac/notifications_manager_mac.h', ], }], [ '"<(build_win)" != "1"', { @@ -541,14 +573,14 @@ '<(src_loc)/pspecific_win.h', '<(src_loc)/platform/win/main_window_win.cpp', '<(src_loc)/platform/win/main_window_win.h', + '<(src_loc)/platform/win/notifications_manager_win.cpp', + '<(src_loc)/platform/win/notifications_manager_win.h', '<(src_loc)/platform/win/windows_app_user_model_id.cpp', '<(src_loc)/platform/win/windows_app_user_model_id.h', '<(src_loc)/platform/win/windows_dlls.cpp', '<(src_loc)/platform/win/windows_dlls.h', '<(src_loc)/platform/win/windows_event_filter.cpp', '<(src_loc)/platform/win/windows_event_filter.h', - '<(src_loc)/platform/win/windows_toasts.cpp', - '<(src_loc)/platform/win/windows_toasts.h', ], }], ], diff --git a/Telegram/gyp/settings_win.gypi b/Telegram/gyp/settings_win.gypi index b97a3d5fa1..1d9f7b3b48 100644 --- a/Telegram/gyp/settings_win.gypi +++ b/Telegram/gyp/settings_win.gypi @@ -46,6 +46,13 @@ 'ImageHasSafeExceptionHandlers': 'false', # Disable /SAFESEH }, }, + 'msvs_external_builder_build_cmd': [ + 'ninja.exe', + '-C', + '$(OutDir)', + '-k0', + '$(ProjectName)', + ], 'libraries': [ 'winmm', 'imm32',