From 3d2f025e10dea7ae82860b4fff4064344827c30c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 30 Sep 2016 21:18:00 +0300 Subject: [PATCH 01/32] Version 0.10.9: games. --- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 6 +++--- Telegram/build/version | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 266393ad4..449d1fc2e 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,9,0 + PRODUCTVERSION 0,10,9,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.9.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.8.5" + VALUE "ProductVersion", "0.10.9.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 5d7b4ab31..a3d19de62 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,9,0 + PRODUCTVERSION 0,10,9,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.9.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.8.5" + VALUE "ProductVersion", "0.10.9.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index edc0a521e..6505e548a 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 int AppVersion = 10009; +constexpr str_const AppVersionStr = "0.10.9"; constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/build/version b/Telegram/build/version index 78b24b0d9..209d05a04 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10008 +AppVersion 10009 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.8 -AppVersionStr 0.10.8 +AppVersionStrSmall 0.10.9 +AppVersionStr 0.10.9 AlphaChannel 0 -BetaVersion 10008005 +BetaVersion 0 From ef2faf676eef7c6625d584ab7b3d05ba507a141d Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 1 Oct 2016 15:34:23 +0300 Subject: [PATCH 02/32] Version 0.10.9: langs updated, moved shadow icons to separate files. --- Telegram/Resources/art/sprite.png | Bin 44575 -> 42682 bytes Telegram/Resources/art/sprite_200x.png | Bin 94907 -> 91514 bytes Telegram/Resources/basic.style | 37 ++-- Telegram/Resources/basic_types.style | 6 +- Telegram/Resources/icons/box_shadow.png | Bin 0 -> 190 bytes Telegram/Resources/icons/box_shadow@2x.png | Bin 0 -> 294 bytes .../icons/dropdown_submenu_arrow.png | Bin 0 -> 119 bytes .../icons/dropdown_submenu_arrow@2x.png | Bin 0 -> 166 bytes Telegram/Resources/icons/window_shadow.png | Bin 0 -> 225 bytes Telegram/Resources/icons/window_shadow@2x.png | Bin 0 -> 372 bytes Telegram/Resources/langs/lang_ko.strings | 12 +- Telegram/SourceFiles/application.cpp | 1 + Telegram/SourceFiles/boxes/abstractbox.cpp | 2 +- Telegram/SourceFiles/boxes/stickersetbox.h | 2 +- .../SourceFiles/codegen/style/parsed_file.cpp | 4 - .../SourceFiles/core/click_handler_types.cpp | 1 + Telegram/SourceFiles/dialogswidget.cpp | 1 + Telegram/SourceFiles/dialogswidget.h | 4 +- Telegram/SourceFiles/dropdown.cpp | 4 +- Telegram/SourceFiles/dropdown.h | 21 +- .../history/field_autocomplete.cpp | 7 +- .../SourceFiles/history/field_autocomplete.h | 14 +- Telegram/SourceFiles/historywidget.cpp | 142 +++++-------- Telegram/SourceFiles/historywidget.h | 26 +-- Telegram/SourceFiles/layerwidget.cpp | 2 +- Telegram/SourceFiles/layerwidget.h | 2 +- Telegram/SourceFiles/mainwindow.cpp | 16 +- Telegram/SourceFiles/mainwindow.h | 4 +- Telegram/SourceFiles/mediaview.cpp | 1 + Telegram/SourceFiles/mediaview.h | 2 + Telegram/SourceFiles/overviewwidget.h | 1 + .../platform/win/main_window_win.cpp | 10 +- Telegram/SourceFiles/stdafx.h | 2 - Telegram/SourceFiles/stickers/emoji_pan.cpp | 18 +- Telegram/SourceFiles/stickers/emoji_pan.h | 6 +- Telegram/SourceFiles/structs.cpp | 4 +- Telegram/SourceFiles/ui/boxshadow.cpp | 191 ------------------ Telegram/SourceFiles/ui/countryinput.h | 2 +- .../SourceFiles/ui/effects/rect_shadow.cpp | 101 +++++++++ .../ui/{boxshadow.h => effects/rect_shadow.h} | 26 +-- Telegram/SourceFiles/ui/flatinput.cpp | 1 + Telegram/SourceFiles/ui/flatlabel.cpp | 3 +- Telegram/SourceFiles/ui/flatlabel.h | 2 + Telegram/SourceFiles/ui/flattextarea.cpp | 1 + Telegram/SourceFiles/ui/inner_dropdown.h | 2 +- Telegram/SourceFiles/ui/popupmenu.cpp | 30 +-- Telegram/SourceFiles/ui/popupmenu.h | 42 ++-- Telegram/gyp/Telegram.gyp | 4 +- 48 files changed, 297 insertions(+), 460 deletions(-) create mode 100644 Telegram/Resources/icons/box_shadow.png create mode 100644 Telegram/Resources/icons/box_shadow@2x.png create mode 100644 Telegram/Resources/icons/dropdown_submenu_arrow.png create mode 100644 Telegram/Resources/icons/dropdown_submenu_arrow@2x.png create mode 100644 Telegram/Resources/icons/window_shadow.png create mode 100644 Telegram/Resources/icons/window_shadow@2x.png delete mode 100644 Telegram/SourceFiles/ui/boxshadow.cpp create mode 100644 Telegram/SourceFiles/ui/effects/rect_shadow.cpp rename Telegram/SourceFiles/ui/{boxshadow.h => effects/rect_shadow.h} (77%) diff --git a/Telegram/Resources/art/sprite.png b/Telegram/Resources/art/sprite.png index e4de99008fbc6f800832850bcf949a29605e1ab5..e8cdf61df2d5d865e00fff1eaa9ad50ea69c8b72 100644 GIT binary patch literal 42682 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 literal 44575 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 diff --git a/Telegram/Resources/art/sprite_200x.png b/Telegram/Resources/art/sprite_200x.png index cd36753b0c8dc588455a1cfadf6b8a8491c99979..366203ca3235ee95ac2c72de19b9b4cb7a8a75f1 100644 GIT binary patch literal 91514 zcmYg%1yqz>)Gl2E!hkR|5`usXA>9t$AcztpARt}R-6btbH%NC5Jv53E(mgbaboc-A z-Syvl*Fu(Sbk5ml?|pVW`#F)C>Iy^z)C6c~Xhceivait4Fe!mQUU)bUpS;``Ktp?i zrX>4P$0Ot4qNk6}Y5V=*w1@?(7^C#eoAVY%a_hd*99S# z&$FZBGtPa4el^;KkihU5Lr9dy@r8+mskVtuFj~;erP)#FpD?cJaaB<~jwCatDnt zjM|{ZSo8Q_jfXVCEAXgP!9G7G2D-9U$P+6r32t@&e(m zm@PPWH?$mmXELD?vcfpF=x%5Ab>(mO!vxg6kEKYAOdjGzg4qglbkgp)cK#Or@| zGYq15E?jTig~1v4R8CcLEGoO+7;gn?)kT7S8@LldKzbhNlqZ1RfHa)I9b;!kXBLEO zRgeV-aAQJpTSUx1(;=gf968W~V)uqT!p}8!vCN zyVe`3-J_H6IytV%knvmT*T4uP+4~%jaD0Vsge{NJGSndZBd%rHn{p=Y6G#~uvG4@t zV=P|k0MBjRU|FEo(VpYenekX&{P;WDfRQ;ZpvLU`XKfG&WOU{s4kyzKHrK0T@Vi(^ z&$Gi%FhU$A1~7)SvKX(I^PwnmK8^GbexL@u#S#xm%jB@)d+OP|p@S+ahRQjh`{VW} z_^x2+l>IzK`b?z6_+uJjwzTSfiO|r}8k3291VIZk`HA>bn7*fa;u%T;i{Q`Cl{BnG zuVi)Z!7iSwlK15%(_A)qr3mVeyvn_rP{SPl*qr1t8bR=e7&A)g*fUw1ebInNx6<&E zylVQo$!v1v{JNsBun;`vlKffYWR;DJ5{6LG=lQ72ZA@WpYbWT1i6Cp}mxn2V`Yj6c zBpdE2F9b-Tw3o*9fjxbvIxw@$D5s+a+H zMi}$+#Qh_Jer(6iXE>mnpz#LuY?gMPb9J~#OzYH4@dhy)RO54bWI`Xe zB}5-*QOqePJ6KyTkYs*~DlMz@B3dVFmyM?&WL$X4MXAS4e1TpH(t_#{-o#@4;z=vx zqU_PU9k~N7#D+w@^+CTNvi^S6`DEYZN4a71(T}#awyob1hG>*wysFcu5E~ntx=XSr z!1bKX1sw=|g?d_AGv0qujymDz@?^lsUNCnZRG@p;U#Df8OFN9bxq`4IR1)UgCH4{j`E;PqJ>tH=6X{M@-fs6f(z4c zDh)lqRqjaf5z2fZA_G>68GhLY*2w-tL?COC zi=h^2&sytmB{P>(k9S%w5P@Ar3U=C<}#3ytYQbB&-0-X5r$ah zxPHVpl+_DdZ0;AgcQTUM4mSv=wMNnTBrby~F)68gd-yc>lxw>XvTj83nzwor8Hg#B zBJO!aAHZwcKfz_x;lpvDnl}*e5Wm^ijA0`T?p)%kdP?V z6W<9@79+RTctaDtsVez6`t~l*_KzDs*h51@_r1ik*wqneJcMg3Jv<-2eEr(q`o8ZI z@9^1JzJgSh)!ec+ya`AW3DQ!sG3_K{BDfb?1!5M~$ZbOLV11O@)v$Tx9kQ-Cl|Ys> zwXpekBiX29+Oz#(2_Ozky0)9z40woVRkl=e>({*R!yazL#C`OWPpwXJ_LSfu^YElC z7|L>M^^>jqEKjB6VMX7^eA5h%P)u<^b46|~LRk!~($3<<_S@?4ji<`>Ji|;DAm88n zJ~%f|G;YRpAXHl=@onjYh=lE$6%Zy#DcSa9yC3xdP7Kv(0>TPr$<6^n0S+y2MZwzV zHZjLO+oQQ}sKcCI6%0^^@m~BX%6>$j;@^$t1W3aaV^vJW6$R`H5`NKWZMXY{9X+4> zfcE2Y>Mp-dM7cc02bE&LrDBGi)yBi*z1vJEAz~wd&yP-Z0FES^Mnz2M)Ee=eFU74T z%^Zd-mUhif=;8j!9 zAnY4*TL1dJC~ow1fD{5A;`sGZxwNEbM7jy3g~&+ofT?V0ZtjZbR&$|Mt!5r@uT@8h zQ?`K}%Lz{Dv!Bpm%H#7b!RlSOtxLSX%xdFl7H}E?>xoXTAuq1qroeAe4<||Zbd{=$ z?}NOg3(?VkR9P`6VJ<-~Aj)sZvOy1!Q=Wm=i-^b>)l?~eKZ`9nZS8TjLMwW^{U_u6 z=M&S@{ym=U9*3(h0NMSsfmMFP{f$HB<<bRlz&BdWgkO4OV2;>j>enkbW7&26t@b0|X zPSoQ7^+HZgE{=knT*B)B)wN+iO@>W}fG+gAIEq>q7DsGtLPU0kio2FQ0o_`;!0$Id zk#qJ7|F_HeZxwE$!%Ls#y60v6wdEB_=5~B)$4c2F?n4n^W@s9Z3GDc!k@HPu+w9J1 ztaFjqgWtS2mqo0)v}`YT-dA2-c{%v{wl_H}cX%&UvMJ|l?R(a_T(De-PjtiiUc^L9 zNTXa)q^NixwGhImiQ)!cxL+P^tSJB&6X!{F%Q=Ik1uXO{=Nt9k{JR}G6YM}B?zJL} z-**F#6<1X`bg((t+WxH1!niCpe@gExh*%8b#cNm!3;}^FoD(|5w8mZA^9R=S8h|Ul zKb$5|wy2wPz2Dhs24uj_6R&oVIDK3_H9lj=Al6rV2nko*z#8$ncyRq&kC9&#(c^*1 zPEzX;KVA6_2oB^>DS(jC(wd0t)hO<}s~=xE8EkEBeK-ThtFw2_g~z8lpcWq{ZIGUho(|My}jG!zOqGK;IzdJ&ho=Ej)X&l9ap z)PtDcIbCYEo-EBzE40I^w!1d8s(84}xqKfvTzf9c-+Y^bkV|e4aX7x;|3%n#t=s}hMcN-x!&%z!w}yrldHTth5~Wpav0GtITIBtrk>Pz zf>oND{WJ;Y&@KjWJhS$w1?Ur9Y;0^@#1_>ylcF8c<1uAg_fF)($uA_cja6FX)Gl?N z`TQA;{qz&SD|U!JwxZ<%t8y6MP$DGdrb$;NQ6HP46qA4$vVVDd7k%l{!~ZM)^z>B9 zt@RP$NP7F?O`wRcg;u}Tpl$D}(!cd`nxmW29_&0eRERJhLBCyqGEs4Ga4hkt9WxEp zPNfv4HagFx7J5$b{~{lVV_@L(ySV^FW|sBlR~woQkI1l_2TREQaK&h8h0B(=y>mD= zqE;K{bERMpu$L|}i(~qOIl*#C4XfYuMCkyMg_Tvd{1q@p%)0^#vP{Q9Z1;kP)m6;s zphG8}{6%bH#y4boiW-Qm$0#S1eiI1%=_ZeS^+n{>7lS)EK6aCl zOvxbi>>(>(a)s|yeVMZuL8 zW=-xS`L7wLTGK=Zh}E%!LqkKQMyNFF7Y26R1dn}DvTtbJ`g7>lu6R2`@3 zJ(hbEL6#PW44sB75<&A!9qAdO_-$PCcCpMH27>F;opW;IjDfXgz6+aaxI3M8p=t@Hbu69O*}=)5aVgg# zWk$YNtt;Zc%*WZnblXgMaL|QV^GF#D58gC^NK*4lORb?inMs|!8S&s>DbYJ3yoM=? zh(Rx)KI`o8zrSMuBE&VUC$wknFk|P?!*3~9CY(6i>u<^O&olwfHK`wundD*-E{jC3 zU%x(o^ZNB7@kF23XRKk`)2YD(W(Hb8+nHeG6;|d8eT6k5O1`(cW_*|z74vctKNAAt zog_+CtSk`-^=`SdGyxmkCBRAUlaiCqi%lpcf;vCwP2qGd-^-)MZqAjbPhoKb$N7Pn zxE*id@Wr*>Is!%*t;<>-u&3txx-?;jD^}LlE#3R)oh$!rDEqO$efw6%;I*9_yQjk~+ds48 zhVIaD`Qc9=#OQ{Ax1RR#`}}6LY+k%H>vgz~FP< zkZ2k_255nSPLlWElA;b^*@j^opodKrc3QPcWYh3FYF)my_uamG_gxJ! zI80kzWMdG}_k#Y7mv=e3spyk@1G&Z&f{ax_33akyK6`03RuZV;;MGe#+u;n6c2{`k zxTl@olmn}J#zm%LY$m_eZ{|WP^^fno#k0ybN3x}$RIUUGPZ!c2o1n_7Iz-pILEN^F zsJPn>V6%W57-1|$p0GIm1e`(+0zdg-Q`J7T@WXRT&w_3isN1ED70cOT#@T9cqQyw{ zLP@Mp$@Y*Ze6PG2^CukxpR1>xDl04dmF{@q2bk;aJjjq}8Ji8r02}A`N3{tOuDM56 zYDGLhN{E`KuXWp<13}wQes4NGDbuaspaD<-5VAEP16lh%4a?@X+N9^5UaOm3YTe2| zpgAyn^G0ZpCmLibViM#-tAe~B;Ca#&inr2O5@4Vf$yC=s&esjxx_HNg(+|JWz7|>O zJ5CqRn~IE7!dvO&!0Yhx*ZOC5JUU*>&aszE`Hl^7|@(_Rs%)DrX#P*_GoZb$JJkK z#5C8B8k!jfJ0vBhixP|%RuHUYw*7aBi7Ny|^#~s#B0qiVoVk@&SP`>j*j1-&mF8w| za7~b~Hq{JAa~!TUAA&vWP~*w*Zj9v50^^{9@TsQG?#?&_xGj+sI=KrqCxjoyo6VonQTDK?qD;3 z$Isv}@3z(G_Lynln+y_7*aj&1dN?^b)9-huCMH~f1C(WB3WkY2K^S})ShM1?^+A=l zuGmuYzVGc4u$l6SJi&vI$RLHuE(||fgPH7pVwrV#f}?f<6tv*^FskCo)+!Y%IVJDShfnDm^hw;BO|Xj43R;xNwNQxSRCHBq9S zP4ozoFCQaX4U~*30fCWR5>Rd#7xXnDB@WpLmsipHBx(_ssxqNbqr8w@Q$7~6b-d2y zWpVSuLaX*Qkv9i_m(vP&qqhuUX3ZKHaW03=p2wSTUaQ{)n@Q2l&RcG2f_8It^}Np{ zRNYI6tC}~{{3S2f6MwDb)z*HzKiU`y$J}CR*%s#SyidR((qN9wbU0e7c1Ow8(e~;5h<_ z#@N-rSEPKk3-wmxe^tj92vCO}SA8vtOJo}2PFW_DFEXZql8uv8JC{UnM-Nc*TD^$# zrlIGe>$E_4v;u=~{dkPf(gk5)JXjoudHeD|0o?W$nz_3Bg0Mjys#l?)0Dn;pCVWa9 zM+=~cEzhwro~>@`dOrkCRKxZ4@u-fBBfg&TT--pEh)(FJh z(Y2-AIhw}T_Jb#$^L#K6n}p9x2~5^AxjgdOTCR&w_qM?g>8J{H8c^n{X9yqWDaIKALf(6|FBzd--1-gi z|6&AEiTaP{B1d&HW~o-vs!;}oNClxKkF^(*lapG%@Z14|(0M!@97|p075uOT*W;%r zSPAKYcH#AVh?M=C6{^X^Ke#W;D~c(ue{1NN>TTA*WRV+6rJZ1`=O)khYAye#mn*|Q z-HDUD9(~8ZM^sJd=M4?PSkeDT)Q}OphQfdm0%XIYFORq4#$0_%2G+)2R#=TqOq`sS zXcskJbuG#eOH9wCFkK`hP;k~jNTyLD3e6HfW*`MW;R%>q*B zzIN~6(`?PAWrh1k^yU9<+xfq`VT28GJvcdfF>9kEdTHz9dO|97cXmKnh8~_4oaMHi z7D+@-4yqv(1i727El<0;x>6f2(pbJ4l_7ThH&HTP68N>n-;7fJI40a&Pe22>t|Nw* zI3a_oxPcqe-{wQ>SJxHjJS^?@p`o0}{1$44x;EJ%;Ao zQbel+3Mg@_u*8sY#HI_j?x;PNI^jHYe3vXW-UHuI07%zxga$mp!mRLJ#K!(w@D4d`{zcsdQ;;Gv<`YxVE}gh zDUyuMk8^ef7V*3x^&~@!VIAfWvng~gbu`Fqs<`in{#W8o*u~TU zXhH(0zL(0ggfE9loKl2SbA4*3Hrh@bX|VWmw9z4V@&~21-GJlvJ^$)9A78?P`ikJd zALvsIg+BL&f)s2PzsY0ysv&wCcT)^_fdT-)-3*<^)r59&IUdR##pzRJweiY&yVjolql`7~Ya1QR^lrxq$I7+FLH8NS`x_VQIZ8%fM zV>Nv?LqUJzGX>`4^nLUU`%x=gk%d%5SRnOxiI{xI{wz_kk*2n$lx7vsBcydcv{;q! z*RKVH93Qcn{lvD9-YMvQy&D2T!+7zs0`o)j>mm}7_ng&uh`C+Z+}QqukXK){)%DCM zahjIAY{*B)ck`GugVVCkuTcD}P-#|s+p$~{%Osq1!VoUQk zN~MRc?;{33eno05LYanc2quHTx;9*t*$UmEI~kfzi0>Z;c*(~1xBd-#s)~MN26iz1 zsnq8(=v-y6(jsx{GI;*M8-YeC53L`^V|>pCpx5lFw9t@2^r*nHfGz+Gd%7guUQ}Vt zWo#IKp)XrNs8*5DzJvJAo1H!K)$?*rQP+m3Xk`NH%?Weikwj7*K_>8^yg&Nr%->+G`||Yg3-SfkVvW@YguT6I_?RSkMcdGfD^c=Lr*`B zr_!Z(dEpMTb33;7y0tghNexL!DlacBB7a=%X~mipH<-i*Q7_Pac#p*>n>5&verb5^ zr>%rDT9nzUxtKKq;PixbfzR{H0sEYcWiG&bB;10`3faQ};df4D<|b82z17D+%Mm=Srd66?;@($z%l$(yTN4qiMR~ zpR4_s^=0@Mk~}oqoA&Hfra}i&#ph6_6^yXxPDM08Q9_f1n$)9pid&m?%BjFH!d$qY zNcD~XVExhJ%L@OYT>Y`g`wKG}MLU>j3mEWp|EfQ3sYpjo*&{dlwIa%!Xb?mfG^OrA zmWx^w-VI`D!QI$|&5@si3t#4AXVagqH065d4xbh!^K2HpAKurO&VH2IE_^i?cV6S> zPUhR zA(~7?L<#@cDj=}+FQOr!{7HJ!u-Y=k4`={i|wZ;aFdN7fSdy?Jl?>-{N>mk^w%XTwP8Z4RMtGi#zJn1acZIs$rUb`gb`13k1lV zj;ugtYwoz@WIA%7R zln#dl4KE?-3_}QAishVQ%^*mBi)ppQa-Ni$NA&4xLF(Y8mVd8BUF%YBz3uRRlE#LT zoZ(Vy#9`4Fvk86j$g`i}xEK3Q!WH=mWsCW=Ma{sNqF-h zqp4nydMz3AHI$Pu0r=rPZd)J$b>Ci6qRW707gHX23p05OiOjidmiVGo-~jLVhhuPJ z3~t)sv|Z(2gTa5??pv2XByT)D+)LGW;>Urp;a-?8>M(CsWI;svGGiVa4;%+n`-HX6w>NcCcb(6CHusU+xC7q4*_g_OIH+dCI6GdX9)x^$5U;K>vr< z!g|H@M;_D1Z)V)s2{E=>@QT>t%Z8S#GCuPa`B)iC-E^s9z3FKTq2CE6b(H9<_v<(1 zayEgbEjHKtE`ZtdHbSCMc0d~>!({i}a#wx{ACkKjQ~#71Vj-h)mPT8=TFPvhZFH}b0iarU2o_|@y@V`|KX583rNYR6pP z*a*xV4{oKCK-V+TFe`YlA5b*&v$%MdFMiVpLB{Ie0oY}ja0GQ357k?ADuLWWhPRQW zx6seD&>VB*cIv;VX1Q@x`>k3uon~)ZX@`%$qXpnIF`$*FOSz^*ZNA6?g#nmtC;u_P z2zUnc;*9UV7RNKL0F#CMMl>nRO8EvH7PF~uELN~dVX6!E(z7pvR{<-N0)Nj0cpLq} z$CZEOmLL7r2gmf$oF9)lJv$5=#*H7Z^_9m@*jOc^dPw_0T*#_G-eT-4!B%}Wm2@qE zn3t0Xkx6W)tcQhD4w5;!w)C#`G{ zbKG0ThVL&)6IFt;L(=M0>t(Flh_L41d>(nivn_#$(wTC-9z`2!CqN4Pm)#!NKpO}^CS+a{4Z1W+=hDvmL;)ziv zV~=jyFJmq!$HZTa`68Xdh7(!yAHS@5(YF*tIhrYRC4AKfQRT820vRYP@uUL-1m;vmW`09qR*bq}hcC4sb70x;i8%!swyJigGJuHd9xVZ+*ey6(Lb=>l{GlN%n8HpLTBc@ z24C8x-(?@%??L)`EJsf{uiz z_Y%t4!%u4w?{?PNDhHK!LqXvogp9A)79Ebp+dF6z|HXr~5CKWP-)UA6#`?#Xc2{31 zEibWE^%~NRIuYdY>06Fj_uFVY=K^CTPjdgEhta#;ImYJ2!TGD%i7?{%5jB zif5N=z6h=C2!mRfeD4Z|K2EeLuiJ_+SKRchw!YDw zQeubJp2^L3-{zAunKqC^ffDXc-avasc@S`f`o!&c@M}Oc^fk@LkROVL%Y|>xo!?cx znxa4BGv9z#8XYl$ruL=v`B9^XI7xmkA(EL<-@J9^S&Spf$KD|v->Ez-6aBe39_;$C z3^QAyUM>1it#Ctr^7yrz`HEXg+j};04Zp#Krp90?&hR|h^~2NFSr6owJ*{1_JvVe1 z3#?$J8=!6w;#1)lSn2sKGZ{qh8>g_m5S#gJG5p=~xT1*?qo1B(m4tVI9nj3mJ|`vrzfzI% ztv-5?$`;eCWCv}&@z8)(B8qT$cRV%I3%BEH6+P^yXLk6zYnHMWb-Q{0FaG}i27C@&^(TEXFK!@ye1XQ_s|A~uc8@GuvTy@F(3oj4qcdJO*zu&?$^70|;^fq}BLnS8P z^Wn7U)Mf8&(9^|yrW$a(kh0lxHZv9uL*b17G8Q8rjO9N^A!$Jc627wwH;Tb2vPe+h zf0XHY??}eo=@wEXxzwA|f$g*3{qDQCui&0&cWby^iz_>_vCi2?DaaQXZ^C-Z z*1l)^V;Ubu?c|GAZiY6^&udH^i$=0`9 zZGM@v@5!A8b`+Xz?-XuUzE%8_$e^;R`BgGMw8R?Y1Mhz)YuN-;MhU~LhJ4k(rXT1X zu&36V?g(B;tflUaJtM!dZS)yd^DsX3B8VS{XuF%ujd$7m@=5Zq`v{|o+3v$DoF*09 z;9qGPvEvn{;3OljTUkXIf}|pz2MB>wjGrA>BG}DBaH8MjiM;jc$59)`t_f(SVIG~r4i&4N(iV6=In~Axe9GVv4*SB8{ z8!&Feq{aHdBoQbKjQL%TU`^=o3zRWg55#_BvP3l4E2#yp4|1N`-^lqkZj`7s1TK}i zy(WQ$;8Bh6QXueCFbbSsRFc5fKc98?O(2gQuZ0G!b`K2ys*JH zH}=|yP-3&vIjo~gJ9Vy8&8F$qyVF0%E9Yef#5F6`*~4<4iuc74?SBEI7Boj9eI&23 z1u;&C6oIk5HxuCH2pM@q0Hg0uvY#jOCmcg--_-_$H&x<>75%-vg@`;36cG_&Ar6fC zLii~PLq^5}f!7P{3V4iIW8okLLq=vpq(@`BvfN1v1$FuIc(07>Ueo)3Qgg^UgShb~ zXI{Tl2@dN0hYH-vn&5A8jF9EL)5KfC%S@&alD!B4L*e(2sDLJ!6S*V^Wqpr2pLf|u zZ5+lZ99}Ql30#bv<=Z;&JsSqmt#QvCa8wUG7)WLs!x^2~a-P?i|DcVN9N?!!2m$L5 z0PEl&Yw@7Z@{BPh2#A(u<_8&;KDx7qHq)G~eIHS%Gk0`<%yg;nOt!L_-s4Ns%IY&7 zg12kRa)1*)1P`t7=qZf;bS*<2*+B$lh6 zwcIWU3EC@es~{%)==-hk5E83(c@$VbEJ_Aw$CC3TQVXp_PJ#5nqNIy(l%?gbyxs5o?Yn%YYkd*8D9j3;y;6hR0rD2iP8|K{q#H6RIX|_8DP}46Or$%h1n*z zSeh3%KSbrU3+e+Bk{jNem#CpZQC_BSCC;ykm~Rqq99Jy4%~b7esB_;08j!t>#`|3| zit0GUO?7h9`%&5aVIKVGx}9+JB{ff8ZSO0gCRv#r%P2Yg%H+dio@FhC(0eKu04o>$!u_msN>?A#=H?q5^CJ3L7!{ zADOkxt&in6=Y|`#cVx42Ue<}U*PNo=FL*^SeZyAj)J^gfUy!HrXXHb^H5T}b>t{l{ zbqRGO=IZIAM-iYZgohtubWKJ)Z`?ZI?~W?{0)f=}bnCkpHlL$@=rs~ad?K9MKdw2+ z&sXYP;uMQ@o;X4!ROXIdB|h|j!77*KvtG2-1lx~$JnwK3=?5#TyNVj`=iO9^foP@W z43p=W-Y;c*W+;7)F7p9PiD^EpvX6ex?-)(@)tmE1y^hOgnM2A425hQfEc$P7ZJi(b zlLPIXXWOTJ$j-nHt&FvB%@E0XJb&_ZgIZ4+$305*HTHAq3Y8UMP=kEmYh;*P>^=TL zS-hQC;85T>sg9|9S!E@3XQBBRprNr@rU?R=aP08(^C2&qw{~fp|9<@V;R;Ox=x3D? zW(^HeZ0(;6Kgf6{BpcmYFc5wC*#EwK!3RrwM5f7nWA9l?vELTVEYGxaI&i5Er)tl#;B1X0y6@oH(=IM<4=!r_{h!v@1#v01 zMuh4HW+7%LXm*K8K*d-t#dHtL4_v#ejp8#l%>(`92ZllBz~%-Pl>OzSnq$;GJYgFT z8@l}YO{E0Y0CJT)3wl2Ng=sD5ySd+dp-N;j?i53BGK%V3Qb$ud#GQY%LU>`0Gmpq0 z7)dgcBIRSgU8tj)^YH|pImnMT8lg)Oi}=y-5MDg-eEJ~_n0*p$&o%6P=;0X#E!pc$ zQD={wX9A3`A&fX>fDmzdeap4^*;73Y;URiF5O8J%y{77sBwZ zxWE2291hog^{Q6bB_q@-?S(#-X$_*K)frI^7 zGxE0vhKhKdb=JeQ@gv9z?@ z8J`}lntka%*HyK%vlHBO8GJ|RHxoeav3FyIb8CeykulwoGp!c5r4~5-0kxwRC>3m! zE^RuxgEGyuiwU&rx)zzX#dEG0oxTeS3i=XT6kCstIgx{ef9H@b?kiS~64&W;7iQe@ zUKuyF^z@wJLx@p>;x+8#+^&hO;n5W)9gWxmn@n3h*wUV!m;X?X0B8HNWq0U<-~gHD zT(n9+trf1%8=_b&%gwx?Z)~;e)!ug8@WtIUvJlvv z4NAMf!$pT&7#qDni4gx-bia~4!Gzi8B zx&=<7og8+Y#sUXN=5u(9OQQ+pFB@rK%yzca?rqWQ)d37>m&O`wrm0#g-6sH|cQO>t zidILaSxVB}Exp*ZnQNbM9MmW>-~Q5{I&kaq;b(UVd3PBo1;X(63U1uM-rXYd+{G7( zW83x`K2(Q$jb_V_$~dfz&3WMJd#a^ut+0rOG_a=uY!;J{6S5 zQ~RsC5-~2&6V}4&g=!qV_IK;CbVxa5r>5z@FaXd7kgByqRrhze-F*iDfI;ul`1;M8 z;a=oHw#^MfN$@*J9j$z`KihtrIeqKK}AlP zmQ7-g)m%V<4<^j4B!?GE?YpqQot+)xmnSj=Y5Ht5YUIPJN_~DYvF8#@jk%*BFK;zu zUm#YLj9i+j^u-*Ys^fwo3^OG&%lLg>#B~KGFP;DPTTBOrgYkTA-bR0HB2kv zRsSJv^CzkSO4x&taGeA(lKz`U5(6~bL1ImTP~{y_QzA-=gQ1Ww%-u)xn(uPf#tBQU zrO^G&OjZtsq*hLEDSUqr)a=$%?c9B38Hh?UuTYv10zl(0N+F$A_t=h-rLP6`IL(tWf-$EF zPJ`#>=9E%(EW~{+@6dcG2M+V-3YRxe__!Syf;b^Qy}71#8mI=xTQ_^dnizZd4<1`8 zZ*VU4g!EHJSszyPW6Rm|b79A9v5oqw!om;n(>p|2v-p6WAi5?zS z;Ssy}C0dPLSVYJW<{f42uHA&Kcb(=rfl|6s1K?zea&mp?xST-RwaRnhc|z#ULAY*~qN1j2<3qilm&F!QS0tKGZ?uwEDb%I$Edl28VpzM3177eGSUwLU@rnFNc?~Qi)q?MFow;$Pa|T zON!|p^zp9B-N_Mg0K8M6lJdK;-Ey@-FQ~0O3enUA91bYtHcPB9wda?}TH;J7>w?bo zXvM|8k}z@kFs`3syeYM`lH_t&2oITMcv>6il5-;71Fk}u1wAqIyIU|X2A2ic376{%K?qC0YGe?Go7FD zlWH`7e_bJcM55&p#=i@J%7!7p9w9(8N5b=opBNHmlCfp`Ld|&?;97pb+9#`YW&Z65 zp8Ek-LIcAJVs7H6$11?1EgvUxY{a$?Kd|8H>ga?#ni^(45>-H-m#MVDZH%#AtJPwF zR1V8l_PV)Zi~xk{nc|nPU=cGu06vH&un>Y+2h;gPkc9dW*^iQpvQspeC&aUYxB_FUx+*S6v`JN{Y>NnvPBYMP zu?v1lT4QbGI}orFdNz}(l%Au46)(@-vZ>^e~tP=L2{(DKZb@N zDgdsI<-@$*pl02o&S7|EXO~oW#t#fI-{cSkxb=Pj>vH3;9)YG zcP^fNQ}>P!C_R6LUh97z=8~=7!%li=u-RSMt<87EjsL$E45%~7%`_2sMGcN%`>-P2 zvrLjMNs|$_kU{(=$5r1mO!l_BSiz3Q7x)7W@#O*NJQ*`myktyTOBm~9vI#bR1dp-X zJ18%NMuk2(-;iAR4mQGzvv*w&A8$22RY_W)r^UJPyH9%7(}%xU{xBK{dW`WxrqK>N z>05PJIvxX_BzDK=kTre956EH#E(A-6K`f(bkgR2 zLmbc z>?BegZOhEJi@ukr3^l_c445p|_#NWdBdp{8i1FhuUSsitxcFUPt-2B-yS15nY(Mf^ zJF(J@)po4Otxpd<3Gn9i*LcZ8J@nAn!bmA6rQtP@u+MVM#N zF;UaS+5qD9+?M0 zcCix_&%m(t0#E>Vh^>L_<26X_OAZX2Vo3w5R=mVPQDXG-|KO4T*FY7cf55W4CbtfX zHJ%SJLE?VrmjsEvkG_#bua_&Ck?@^<1oI$61!iPD0q$n zK^6PQ5o>ir0qqDwcj9WAV)6f!btQA;OkA3% z6CIa@5SU5puO?h1goMqDwt?a&EQh69ZLPO!0WDqYK1r}BuUco6-!9;Ip>ek_*N7M^ zd=jXOT^dshMe2ak-HHDi51n*x)nwl7TI^dDRWVgT(1zg-c0py-mo=FQmq-}P+#{6A z1LU1%5NiF^(&i{QuIB9A?|-=fT9_?DMLG0M^V!x|+BXkBwD0y^^x(}^Zu z95l!>Ob5{bD~q>$g~AQYl6#8Th3%%?H(z$-U$(o( z`B1!sK(`!y&a9WNnJt7Dy_26l121eRhn;(P`bW}*9HbGqLAW+zE8RTN$3ep{EEW(> zFFpfrL79#TQN4ZNrsG#YiTypl0?@6&&+w_3C=@go#g`tY=zKFTC%F3(itifq${zYE zpax!VgR--Wm{61$KLEvA7u0M^+FK_sm-e`XnvABOf#)94zXS9K<)?JPFxj7tyPKLO zl>HaqRFa1)0T2bW$Zd$Ier^*3pjNV!m&K<`L3RqK6W{epG71~HKw6lc*#K!H;jA(L zL)Z6<*P)>#B?3STEC!$wf?fEJfE?pBT?r58HfXf1u}X^ys@ZMi) zCo|+Ue8AW9r#kV@cuHxS(%nX{QX(65$>UBD6u)z^dunJK>RSx*cjd0;(K7xMBs!K} zLX;6v_611ML_HU7etvhIN5{v&)6)yL6h~ekfC#y(ZpRrisFWMrs-}Z)Qq zK1zit)`k(T&qG^RBQsgcR<>k?qTt_#u6G)3--`cBv#Fdlgu^9rfKs8xgtBLDZo0PI`+RTFI~>r} z$8Ka~c~3rOdR+MitFmp=_V@vR6f*hM9jRf>vfQ2yyN<+!&ec zZs-JhVnU)$rr#mZCcoSyKb~NceGAY)#DxKkuEfN|BDtyn zES-1j!+!m-@zb}4C3)YpW!~*Sk@>6IL_s)UuOoHcnU`iQyLSaWPyk-Rxf4s#y4w8P z(yG8q#=OOx7sMRNx4+9zyAmqi$WaLicad`)J5g|^VXnd{cT{a9H@Oanzc;~67-+_QCPS%^>XOMNfcKSBIPpSvAc-aN zNRLjnI$>2GU-${zu-!9a(^ z@MQZCh+X^Lij|Hna_mO^r4UE!{e3_!kNS<4#0ALqa7?$9EAl_sHVe9dWA!+SA2nzy z*VnsoFoG+_{If5zm|L#}RNctDUSshv0=5~N9|x7N;iF^vua1-s@A2=krRu1>MZ=A+ z08yI7Yr54urV&=KOt8E1Np?`ozNDdNrug>52PLhdd{IqN%)(_Y>@m~(w{n`5`bSqT zIW(`z6&T|D2l-N!muhxUY)KIxP;QX+`+R6uKlb&4c5xewxcFFB9Q)UhJBVf^0e>?X zD8x-~2pmcc(_C1u_JbpOeF8aEFsvVPH7Om%>%DN2u%m9~B-VjC(=J}?t~NoeUQ3!3 zvq#@)T6%xm@fX3S*I!^7Irl`r5NZ3nVzOh|ta*62gR%W8Bb9;X+t?z)d87)4xG}!Z zDJcckEonIe`jJPx8D%vI32ACsAFb=blUF1rdhXsbbIlC=>NV_Is{T3slz+11-#rLH zL6WGPY#;gb3KE?KltQfxp)CcWh+oikBS=hGerzN{VkVVYKQzcTK8L8JdoejEwRoXX zbB%yVbE54mM@_k`8;9K!st$ySaPn1mxemSH_yDpa==S(y)YYmG*a3Lh#S9Wc%#S^cCqc-aq zwqo}d^*9&8Q`Wz2+xCKvucp=K5FZ*r_pn6s#U(eh0u9WDLo-9RQ=FgT$pd7gd0jad zok~$pM<)|M<8x=P>zJ;N{P!8^*qWUJaX|6^SY}85DzZW-(+NXKu)bWvY(+iLSVAu5 z^Finqz3(ax8~IJphR?#{PQ!!nd6`0s=4j^9s#_F|B_aHfvN7fx73kUSTRy}PwNLsA?SMVVLsW;i1&QiKJsYP z6N@j4q+Nt{sG?ZXOXqkx;ggYTF5P~f>_2QvfX23GhF9b=O zP`)j`^2w-QpIiuY470qWqI8N@dfn3EmV&+L@^EgeR*Zk8u5$UG_r<>z-z&5UfdrT5 ztTyhLm|U^v8*?+hmcea0G{1KOue+GnV(+nXQ3=cDX};Rpe!w0JIwm8%&jERbge*jmKj;!g#hEJHgL)?tthVNI)uNH3Mmb9Hm&!Y$vx9wZ8 zFK+JJ+@l~m|HEN$)E@F%FD1c*l@aGjN=ust67*?M9 zDOBod|@uRXmeP3msS8>UpU3(~0~gnd zMoLi^c&Dg{H8D9U`k)dgM+;@7x?Ct_uEg2F(gv!k_OToD#1*J_HMFQf5OlW zAo0#S>x!QD_?>0lQ{NQL5 zTrEc={_s~I4i3g)J379%w>L0oX`uOia{yPj*<~_A46|O5SzcCep&`7S@ zF0dxd8#`aG5PXs2rDNcZ8l**4fQ}WC@Z|FPN2mp|1H9^u2UGrF_ER`I%4qXLCi>n8 zt^`gejaQ-N;)A(!U^}%)EBL(wWMxjFUbr5sY`FYF!ks9JZ zlKiwkSP!_w73=VBX_bPH%c;vf92RC@3inp`evq!r-&~UNVkY88o9ZATo3HlFBY*t; zGs@uk^5yE6V9T!%Eg5LFob>!sBsxJ{j!`r#$CevP#aK+iSBN9(Mh3le7PxZCpzgDUl zDkSLBp6Z8Qq%lrfh*P>h9fzlcmE%2bzMn&24*~Fu$U*Xs5*YRCL0Tinh2>f349sGx z-Vqdhzzrmfgy8b7Et^*kW(fRah#&l$)gyC5JwJxVaNc8yZjdgtNpx%Jd5=deARSy8 zhhe{-i%Hhcho6`*%I0By;CG^E0I^ur!q{J$A~BAv5s;(zkTCgb9H|h%)uJt!*xOLV zhQXrMa=D<^Tks2fz|)J6U4p?=8C`&mL)Q}dlr#Sei72%z>TFr5+}$`TGt$1NeAfX5 zu(G?4iyKXbq`X>lqzHTyx{<_*!w`1sbVewOPIp$rwU?r3%V zAot_qiV^-)!{mmJO)I!MAwfgQ=UexPd+9;yC%yQMaaMX<@k;$HVF4k}!FtXgP(p-itf0mM1k;P0=t@NJNo1-7HP_XGgeL*r_yTel$NfwQI&5 zCv+zgY$5^p$rF{74Tf_Lkr0XJ4!<0AlN%Z~2vEOGsPkuE!As1dRtr;f;)kJS zy^%xK1<^?guNy`8JD1H#?k&R6{*u}(+9@80}qgPV|1HGkAa5B(|+|CKu*-oRjo9A`~N3BZHXMPDTW zQh;Xo&<1e>lvS>Lp)_Nl9qE)FN(rw!18>>5ET;Qd6YbA)=Jg8N4L8r&TIF`6ts%SF zem)}XGuH%uXQo#~07LnB#$;UIA=niy%k4Px##~k2g^}s;<6MW+-3H}PAlJkC_s;6f<>Q1=im1Z; z+*f_Qc8md^uzJ?VA5;W>N&)uk^}_ku(O|I-R*W`Bq>DF8c)Pc5-%2~3pb)Q6ylMX4 zfd4?!m*1>A?b;prs^08jScu$fnLBqf#E}RRJ7-u(2z@3z(ow1Pr@du&lx$?P_k-5z z?E93*(tROUSqh5xp09}jDxNQ8VOieJP85L4NqV5-+4w85RS)MB;d#`{q$>8 z-*=r>1>f=~``Ukt-)>86zF*YAcQfoBq32M7r^L9Df4$1>n!q;jDXqO44>E>k7wj<*{ zy`6bJ?;SqdwotRw(EBw0-_He*#^3t^{iV(VPL<5@>KP{de6io<+(94OKDC$6@r*L zA{oe!0QZ0Z(~3HbK|ZAf3?$w>JTLce7yz;GB`paEa&#N~fM#c#Llc7P2Hf;sqYgE< zjxk6=v;`a^oMy&6-ToO^AYv?ZIcmM>3wf%Anqr1e(tn8_HuFOPj{Qg}@6_g^u-j^z z*PZ76Jsu>@SnRRm7MhImD5MB|L)EHJTJ^TiMSz9TbfT^;;BZ;XQ~t-;a`Fmz2)h#`gHBN&_8r&xb5rxj9C^GwdOBQl%#wyc({WhZ&n#hjHpv_%_)TGPlDbuM!fB4tJxZ*SV(`p@7$EjhX+I= z6YepGg}`xK)z{JhvmVsHt$s}jUp36zVDjm6%>S~d4mX4#fAajWzPA2WqX|&f*IQ|E zb;^>2Cm^;8Lx-y7!}nd%=$@b|Wycny>L5$LI`?EjRZH=ZuOpu6YLE|>GEvV43oWUp zA~xYYP=5&EthF>cWPdpivg}}kcyH8JKbr~i=_s_Y3^Dv-(QiMytHxHkckLwCS<$Uk zQn;7)h!ghpskPYUe?>ME6uyOO&p|e0YIrijfAQtC|D+gImvfRjLs&15sLK9aC{hVu zhUbe;Zb6pctVLcPTVDk>gaf0|%ZKOciQ!`e8t^qYFO@jh=;*$7KNMoDZjIQ|`8CRq z2|m*P+Vuf^qHuIr01R~seJfA=;AqCNqBkWvcNj$L^Dt0T`++$L%eJCNT3ptiK;)CO zm7GU1B;PNHt4eR?Uh!tiIrIi0aMQ(c^!IN_%Zp_NCrl6=Tc8w@Zag^WCu}R75|ZBKTHonVB2qx3CFXD<5<{fM zMhFx<&6eIGBRKz0Sj=6Y(T5u&Aioi^NAd#>RDg2k zvVFHJY#Hk@-S0oWYesf|V1bAB&i_~)!wYldyo`)l@A9jpk+OA!3mki|^AU{qZGgOa zzpRH-d9y^WW{o*9y5Hf;h}`YwaY}_?d9!nKpT~p6Faj$0YaY^X1W(fKy#wJo0zKE^ zW5eTjN-fwE8WsENDzR5*FJt$GHnpd=;kANs?lPOta*`5>qxvwlL4%fMs1E|Zce!Bxu_H4q@Oz%@B| zr^5H?sd4!UEQamrWo;xWIOSo?)1%8%x*kab7QZ$9#47RUc={@H1iMHGjQ3aH9p=E0 z4uvw+%W_Bu$Ep4Vpm4@*S}MZDKPw!+e{&7!-j-`;l&|a6p_4imq;hy!+6)O+2Ld7h z=C~M{o}O;*a&>73LO)Yjyrsh$bHHfihi)r8pFBf+aX?*^SQs12&`p0-?{NA~IaHuZiA4&@pyg7@9)T8v!75r$YpUBZEXV zS-zP&x9k~Nv~jqvF}kP1_Ox*knEl6}@Z@%f9p#s*DiEsF%nbmbDMmy*as#7s?+B%z zSU>G<7rp!9DnOastgCHQKR(%l0-J#+&t3Y)n8RVOiPo3P_Rk*_;TovM8#Xc~0%Bx@ zer@w;;tPI2z%_@AXvpe#(QWmwJtVlg24h1cPr4Qz9T@5^Wr4+(%xM+ z8g6_`nBiG1rQOlLJ*mi3(y`@>HYG+M;vh^k)jq^VAL2?RBptPT_%}P*f=yJxRB8#0 zBI2m=jX|He8uIwDgQQ{o*b1t;UL=5HO>^w9Ja<`b6BJ0$QoY>PusHe3!7&`#d2QXLcyRW8Gw6g@71#&Obr@CZ__;LSwiGRMoR37ba^79Z!%gz!lA8 zoYd#Ms2@WmI0?Qwhfl;_=VGrk2BmoeBO5DQCZtInol;zeMYeg zZGGJO-qm2P$ZLl^em!?c8sNQ590{T~jmJuV(=-F)3P5MqfX#R1eV*A2?%&?V;!leV z@@MMf!0?DRB{dcOhu4&ASJ#V#V+1c%(g@7A$ANNVf*zEWdasFpj+4XWV*l;Y#?b<1 z@J!0tYe-2bhbcQOSUF@&Bt|MF#V}UUFYSd1Ct^yz?ZW=4qD0KG_uD zM>YF9l|5r(O1oK5fh0^PN;%2a`OFP5Fs`gIEW60H>QPt zQB36?1$!O@; zvQAj_Rvo4TzAN_ORKfo8+(yO6$Ou7;jUWMFOwtgrm3fh&p;Ufr5skp+%7FEB*_;dw ztzjf^MeWoZ6wnRG!YSL%*NAVnJyoObvHd0oD4-#Hp092(V5PCI)`m+dAL3}?m93ty zuK^EvR$l^I?hrFvAb=^H9dW&^L$vEZhi(L4pIO6I{b?IGfMv+gqeCAeo{!xw=!4}I zP54G=#B76d?%%wOuD@hjGygv zOfR6xuYbMziDEa8%04Mea7ql-(G+!<1j`(c>TR!301+h1-6bdaBa_E2Ha304Q;}{C zC8X8LLWq{FSz%9dE{7N+X@n0aLYlrOWOT_L-7I>jlN;TxZ?^MG^PQ~4$KwYgWU3L7 z#2zHvHx4W_g6gI@QvE>XK_nrv%g12<4YEK3rvq92&f0qS+R^Dqqc%C)P30n7;R{>O;hSJr0>s!Cs+n=kl73~ccaqVVG zJ83En^{An@rG&$elJ*AaXa|WN?S(STMxd&Hk-sU-+~VE1gQ#9{Ih+9(Zd9SVc?}2v z#UHQ74O=Xus(rsSl5_p%SxzeXl7Uz}A~OIR{${Z~EJ@I=>Cr%jraP+9!CdF_CzVA^ zzj^uhk=;Ex-khGw48hkYd#=yy*cqBEY*0-~UIIv<(5F8-d|j~W6wiAJoMRkfhC*vk zC%d}`Ik%&mnV~5#qV%3ct6fvgw5N&%IQ;WgtAYH-7}K&lzN*u`` zsw5(9>$0+6-T}Fu7iJ$J(C`}-k)EczOy|$x|E~qeX!M|jUA#=YO5i*^^VjN6eZfEE zgM}T>@|nViOzYoDmZJ7upgdm~L~}159-I+dW^g!K7(|W^%DTnyWJPmM5R^%372 z3j9KZ4S^G0KJKJvA83jx3-W#HYHCi~@zN4ic%;V1{r6v8niW?l&Q~Gm^-&i9#UF%T zr(%G1X?s{d=r1_|O222%G~;u^8pmD-8xdd|9j^R(d)#a(qAB)`|K$sO-8#As4_uLp z7p24mvQ?=adl|8Wq0^)ret`^+zmIp?*(%yULSN(m2&9j`)pBphR1D034UCS)94xh5 zQzV*(2-tsC(-m-FaWl=CGb1DQTNR6NIVPj{O!GFqTg zP(i%S4)N(M#H(t3T-c!>GcPV~dhn!fW#x<&v2!O)S2V@iu86NF2aS8Hov4pvwfW!( zRpJH%As`tdYI&ijRJeQeYK=b(c>3>i)p1L!zia%Z1Jxm-ESS7^C&38jYdZ0#`d(h& z=&*`I48A&QT{7g*odn00aU6}VA+2I_t~_ZLTLpiEqxx~$5tyJF7Uh`pr9dfhGo;P0 z&5RCIjmuHjeOJ3t6RjF|hFCFeDS+p+-j(7=8{%g6WmM0HYeHx(b1r_2mtNvO-iBlG zwR29EA*T&lEX)#O^1z-1ucRnCM~Oi0$N{Hn&M-XZW8K5&3_N&%gP|!}PCz7oT#lBmM`zjq>PJU7V7xkaW?(aD;?0Bc2Ajt8TNY+1qxUHW z{cq0xLuK0_WFb|wRFS5m@(=qEt(2O~yAvke=1sjhr$b!nGNS{Kjl9)L%KBWz#`K(J z#K-}r+zMxH>iIT~z9f<-rKH@x_wi}pXVj6a<{zrrNN-rMsW%2wfNFpB*~Q6<+2Bx}6D>CxcJK5M^PIzC~tb%1} z0#Huh0`8LGiZ??9fHQT0Mv(4D^{7|^;y0jQ^ z5l_;%bLYrmp!JDc!DFziTK2&S)Z}2n6Ta+Q3>KPgxy>8hRRy8*qSaSx6mO#e<^&u&U=yz5K51s_355lS__GlWgDVa)gob2k0 z2Ga+Gfrb)VQotpcjt}+nRDFw*aCnF~*pcV$>X*i^qA@E*r zH>4ixno(d%|6Wa(Yt>mCtJXyZn<931f#`FYC!V?3@WXw(CTs3_v2`PV)5I{mad z2g)W6sW(^csD|87bGV23Cl5kc5%2-D8en?ArwztAt+?hfSDmvR6oXY430#D=MmQpi z1c|9bsBZYFTXG92e0_Zxm+wx9!mqAPt1{m{-N_fry||o_gL({AMm}uxs09!V-MdDl zq3_MNl7UEJK;kAr*;`P#xJQs6cRzhpQHYaR??ULrBhmmU+|G4^fHx~Aphpu%ie9xnaf}@$WR>ArkVco(U6is2n%| z{hpvky3fNiW=Nap&G!g56Hk?@$a67+iQkT2K|g=LViSo4eOWQ6FJ8yeT0H^lqD#^% zqBtXKi-%93zc>-oiWbT06?12+gM+v{Jthw?C7#UO6fcWF<~mI+MAv6A8T;NjGha|7 zZb)5z685}q?~RPt184bjwZx1{Tzn-@-l1a9;i*NqrtwreAcx9{I{a%Xc}k8=yI~Md zOIIC1IkDXr|YU1oAGPV8vF{( zU57C`uFbYXU|cEQgb}$+{7VbwwdoyB8&bYcfu>EwezT1m!Q+hwg=a_g1}v4b%jeJk z7Ajy1Vha!Z8&>$cAv_Yvl^aAG+u~_bIa%>LM-fx9I2#O)|7P@QkqT=BME(q-hR6p;?L5COj(Wbgp#&A|jNN@bU}gY7 z6>y&LW8u2&`<5=%-Cq+SQV$Ps>_n19ptdAp5cSc`AX%441C_G}-1rT3QH}gT>@)#A zK`8#<-EJdv@St+)RgaL(mO`0um@?>L-@N5Y0Ogm_Tdw-{vmSGJdvpQJJ>wMhl6Q!~ zRHtd;zTUV6a(nNd(};TI`g_#+nf$A|x#fw$JdtwSmIuYZ`<9#XI^=K-~U+w@np1$bDzc2|i(n zdxM^L8o8hsT+&;s#~ON6_?16=Z;5T>i?L_gtcx6JlHaMmL8DoJ*~lA257kM_J}&q! zuZcz$;Y-A5SJYmFI!3S&z9<;A@Vwl=RIk);%cOCn4)6g@l#$;yq~*EZf;vSSwUsC@ zx!n&k!5!cQL&{o4ep>o`nZD?xEFn~h?~KaA2Vx5|cfT6e?PE~ag%>_QJQ-#`;k0wx zb=FY-FB5hYv6{h$MSpCf*M>YAjjpAx$@G3V?nb_Yy2Xqw#WuOwDEhz z?~d(G1*+D1NvtDWqXB9vPOFV?&%H>2FYia5E{D4Ha6-tN&UfVcdl{6MkR&`LKp7wC zl|`Q4KpDt}5ulz`J+G35t72;k1Cx-+^?(<3cG|G}8~sA{ zpx;i1*uB)Ai~YJ}FJGOdg*d{7r958q)G8W)#AU6I1~X%-EwM#(5YAuo^Q&iDf?w5; zj~^N4vbD;Bhjq(2QlH;?!M{__UZ+X6{Z#a9HRqZ>euJhp4XKrZdxuljIwf>I$xmdD zzTZs!4*X9UVEl(Jc%ymu2;3eBBHf|73f&{*)=7z_w!*rVLxd~_rH+WSn_rQ50nI?Y z@PtZxj()V?OJP>M;RIsW_HOkA74|nc1=#cGk!^40lYS9QPs)?S!$#zmuiPKWJUpKJ zn&(cwZ7ny+l?y^TO@>x77x^w{kS3#4x)>695lvyKRI~f#tm|dA_H4_TuB{0&#u2xV|Vv!9cZ zVZO@GR8Ya38WsN8JHD6Cd}k#~Aa_eBCo&T^(s5(EC)r7M8I_^NngC4_-G+62kNvs& zCN`C?`}R9%h>vWXgRTl@j~i1Phcy-E)>{U@H8^@2+C_s7zRH-qfrWk{3<9J+S%81Y z#`l#f<~ynfELfIly)WWwA#nHuHij#Thzxvcd*pZQt4Kj2Gry@LJUDGVQaIRhj;OEn z&6AoD+hgWnVDm8Y?}U}infOx)VStNNAO3NnW4S6ib`a9wB2W zsvm+?{nKMuIe^G}7<7O8MwzURtb#_$+)oAJy;hl{w?ASqJk2fd4{z`9_{48sVZ7Tf zZB;k(G5`!D-~7G``WTCRNbp(Wa}#}hYsKPuPiVu!cTg=_nkAMKT<#!lfE4ar-S}%@j8n!64Vv_sHTCVn zQY>PyB+aF()BW8I6_+|8gcrDzYX7Ci2fc>F(6l(ffi6(7vrWK#$EI4wrp%!B%c0Go z;UMFfS+q;%bKS&G++yIui0_v8gE)j~{VN_ux!IYHCvz4`b!uR@)b3jZrrNAsqM%~% z#xJ=G%Wb5bKrQFmHS@`SEQ-HHI*Kv1J)LOP+ZX|U&I_g$HH8&b`K{YGH9n&JxIx7SXZ&>;`j~@nM%RCa=#h)JF?46+ zONEZP5X~%W8V@?gUec2kQKO4fpC!fu*AFCz@0C4r+jB}TEY^aQR^}VMbc`G=rDwF~ zY#s{OKR^4pXS;P>dTD{&m@j+LpNS(J?xCw`qzjLZ<2&7iK6_Xs7Mep91#|N^!)Lj5qYsY(!&Y+`GB>~XGg|mqoNc8}@Ye1`$>5wh ztN@lTbruy$86$IXGb@DaMFkxu1!2k-cyoZZVa8m=Dtrb`l33<{VC zK&oD|W5@<|&tAs&dJUnd(qb_>GYSg}JG*&?ywAFIph<=|?qUDu)t5G$7f^4A%IPNW zHXjNn>dC;^LtjutceUDB>b{kxqs?Nf;YtrUTwL^aMXP^|O~el+4z?7TGKw`4a$&d1xLvolz|y=!6+ zU2bpjro6(QrCnFW{cd26QnCGf?1ePa)8KKu-mskblUBrKi>-C0*ulx!%Yqa#s|v#{Zk2-@gPM_}>k<>c;>HF3 zb0S+oukWg-{QA3!QysLuSmc`$73Z~AXc*WxG#ntHMp;$W|HqHlwY9YXfQ$iwMn+=9 z^#7NTu-b!G@;YM&PlZqJTmwm z;o`#d8QfzXUapT`o_EaMvh)B)Mn> zfli5v<>DC~-e$saolbc7SD)@TU7oH|NXowpLrJNp6k3C?oVgaqiGOf>gZQ~e(C|p& z%cKiBBZE0A`|HKQct#_>w77H@-+(%h8(2dZP`$`&Y=nS#sDXijmxaYZzDuPQ;rJ?@ zfYW<9DH0)wDF5+&q|f7-aOUwMb9Gj#8z%C|EIqxYd{RO_bsn9XL#;}pd+-*N_n8+oVJpM{4lI*Y7GM@XA`qTRJ_p;(-K3y;}#;AM0 z;nRXmCQ#VGz82j<(~AI_1ZCPhpY1+D4Ln58-?RnbSNyKY+vtDR5&dNnQZ_K~Ti*MF z#?Jf?)Ky|Y34ZpgFB#xKGJ(=vtz-bu!hLEG-`(fx!Ii-!V%K-Me`r|oi2x}!X+%ZI z8RF4$nQ{vXkiaX_j@9?pNuaNiZ6K~unHP#`(p4vZ++TBAil^LI{qVGKtfr$ofJ;Og z&sXa^x)6MI@@=6@hmk1jcI|hCyV%lwZ|6ybM%q3ZYW227Hv$-jdkFOtwZrH;Si_!) zq3~F7FB&0|)m8|O<25rLOP>^I_tSR14?|x6ikV*=H0ny2nH^Dy6`jS5dPGAEzf#k5 zdJ|^u*BLQ&Sw*e__?YYv#nPj=HRD~ zQ8E13zmMk^OhUQb-oHQG`mSr0D>!s}-P1U`9G$?HNfelR7fiFW^VW(qLi%jKXE!|c z?nj|n>6WDB)Yg7#VV`}wxVs?RyoHv-`Q}08;D=|GPqoYv-QvQA7|0_xr3-~3t+vl4 zj5HB_H`mT4c%_x|2Z_7-sK^dd>zy!URqb1q~_ z!~$cur}2xo=XnaUY9Yz98KB5LOiXnt2Lnaz+@@M9-;kx$P4r4RIXP!{Fj)1liG!&hxx`Z6Y+W z@{{;QEZBZ5W$>q31vxW+F3@*nEiURJghb=E0Z@It_~yMMgf(%zU=yXO1(YcxLx}Jp zp+X2zFph0cP}ZJG`3(~r7JPDz)%fCVCq5A{W#}T{Klb^_7tSTYVQRrs7-wYGhVS9D z8=HxR<*!W?C~7${0>CC0wP7X#%|%Ggsyw)o7bz1hc`niL(EQm({5Ef@2S!m|qvTGU zURl*@egMoF-2*oi@1!5~xN7l;u2Kjiv%Z3nfnq;(Soya%3BvM*I9BHjP%mI}_b9ZF z4Dr;xEd!NkBuhLdHI*bkKObrY;o;?71EXHy2XtDAL4zh%1Zbc#BaA@uUwv$KS?fXq zE2PoDifN9tVH_D;5C$I_7S;*&u6(@nf&>#|t^QyNPkQ8Xm{R-<=*g&vKtjp87$J~P z!-~AvV=L>25aZFikS?KPf!PfQSSwn%0XUl60-JYOC7P!-z zd0TUDaPQ~v4TEXe8wd<1!+ShDAa;IJmC_zbt6Vc(%$o#I*4|%$uH4*slD~D2pE)lpyyWj%i{6 zo7J%-V@y@|JHTv(`?{NT?_l3en}oSGchrF>0S!qv4}P3UECP~xjrGl4uCJ2I>

$uO!eBgB6nbPOjHh)U@C#)@jDH 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�j-U3UWbG<<0^&6N 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Ξ=k?^xFxD?uQ0HLhtd!&*8uF=c0!0`m2ptbzKpyk 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 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/box_shadow@2x.png b/Telegram/Resources/icons/box_shadow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..06293b7405db47e11a8762cee0a235b89b118545 GIT binary patch literal 294 zcmV+>0oneEP) z7{RInN{(%EcD)4LC%w+my{w27*a9pV31M&wM#(ehk$4J5ol&#Tys;(65l}>$s=7iv z_aPWLK|p)-Tu(W+&Q)~)X5ndYRN@}mx2WtC>~%!2<2b&+*Rjtvy|}UhY{^TGky3AA zA=jC?PQAz3`905*6>o_2j{sX})kuv%^K6~p0!Le&w?+2%r@<&ZG3W!a6wIJV+;VUv s;t??0{D12BZu}p3*fQAPZky% bU1cXu%by17vO!3R00000NkvXXu0mjf>K0m= literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/window_shadow@2x.png b/Telegram/Resources/icons/window_shadow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d2e968fdb76e700b7194020b99dde40d8cd116a8 GIT binary patch literal 372 zcmV-)0gL{LP)Fk0%rdB?#pWzpIXXnOHiQ2M6jtDt2J)c^h5-u6ey*fKB?WX2oh}< zHf!6q!M^XcDKAIU`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/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h index 113ac8aa3..71001d8f9 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 a7acde231..f45ecebad 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/core/click_handler_types.cpp b/Telegram/SourceFiles/core/click_handler_types.cpp index 45f331df3..53ea0b47d 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/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 757f55c10..b6b7dee00 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" diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index 743705025..78ed3d010 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 1045d9bb0..5876eeff9 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 836b2a531..a9ed3f699 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/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index 5b710363f..df5f5a7b6 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())); diff --git a/Telegram/SourceFiles/history/field_autocomplete.h b/Telegram/SourceFiles/history/field_autocomplete.h index 9f824a829..d0579b16b 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/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 84987f2d9..581d15b8e 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() { diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index ab8d8282c..cf6c62bca 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -21,7 +21,8 @@ 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" @@ -479,30 +480,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/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 700ea0174..ca803e083 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 ff6a668e6..8e0585547 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/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 5ce17b79c..706fbfe8a 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -43,7 +43,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "apiwrap.h" #include "settings/settings_widget.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,21 +59,21 @@ 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() { diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index 804a6b01a..c091e5e91 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -22,7 +22,7 @@ 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" class MediaView; @@ -54,7 +54,7 @@ public slots: private: - BoxShadow _shadow; + Ui::RectShadow _shadow; QString _text; int32 _textWidth; LinkButton _reconnect; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 9423c45ef..cb086d89d 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" diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index 5b9dc024e..ae04b731f 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -29,6 +29,8 @@ class Controller; } // namespace Clip } // namespace Media +class PopupMenu; + struct AudioPlaybackState; class MediaView : public TWidget, public RPCSender, public ClickHandlerHost { diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index cd785b2b8..1549d5019 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/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index af4744cb9..fee28b53f 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -138,12 +138,12 @@ 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); + st::wndShadow.paint(p, 0, 0, _fullsize); } if (rtl()) cornersImage = cornersImage.mirrored(true, false); uchar *bits = cornersImage.bits(); @@ -253,6 +253,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; } diff --git a/Telegram/SourceFiles/stdafx.h b/Telegram/SourceFiles/stdafx.h index 41c554fad..5a62d1128 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 d7a73e221..d515e3506 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); @@ -174,7 +174,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 +191,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 +213,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 +237,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 +275,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); diff --git a/Telegram/SourceFiles/stickers/emoji_pan.h b/Telegram/SourceFiles/stickers/emoji_pan.h index 71b542af7..488f5c86f 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 bb33e2d24..43bd13f5d 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -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; diff --git a/Telegram/SourceFiles/ui/boxshadow.cpp b/Telegram/SourceFiles/ui/boxshadow.cpp deleted file mode 100644 index b556d5719..000000000 --- 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 d23e422a3..8292f0187 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/rect_shadow.cpp b/Telegram/SourceFiles/ui/effects/rect_shadow.cpp new file mode 100644 index 000000000..e50c0bc22 --- /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 3eeb30292..6822046b9 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 8dbdb173e..6385060a2 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" diff --git a/Telegram/SourceFiles/ui/flatlabel.cpp b/Telegram/SourceFiles/ui/flatlabel.cpp index 909f4e172..98aaa94ee 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 24e5a3942..f0c424cac 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 1aae73771..c6230c438 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 56f28caec..2115679a4 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 2bbf65890..e6649b629 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 ccc1e8cfb..aa4dc29e6 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/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 4e82727aa..69abfe22a 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -412,6 +412,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', @@ -439,8 +441,6 @@ '<(src_loc)/ui/widgets/widget_slide_wrap.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', From 4a5f4675604a03cb0bb00723356b361b3b66b4dd Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 1 Oct 2016 16:15:27 +0300 Subject: [PATCH 03/32] Version 0.10.9: fixed interface scaling and Windows build. --- Telegram/SourceFiles/mainwindow.cpp | 1 + .../SourceFiles/platform/win/main_window_win.cpp | 12 ++---------- Telegram/SourceFiles/platform/win/main_window_win.h | 2 +- Telegram/SourceFiles/sysbuttons.cpp | 1 - Telegram/SourceFiles/sysbuttons.h | 2 +- Telegram/SourceFiles/ui/style/style_core_icon.cpp | 7 +++++-- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 706fbfe8a..43c59329e 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" diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index fee28b53f..343c5d4df 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "application.h" #include "lang.h" #include "localstorage.h" +#include "ui/popupmenu.h" #include @@ -143,19 +144,10 @@ public: QImage cornersImage(_fullsize, _fullsize, QImage::Format_ARGB32_Premultiplied); { Painter p(&cornersImage); + 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); diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index c3bca3270..458788064 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -21,10 +21,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #include "window/main_window.h" - #include class NotifyWindow; +class PopupMenu; namespace Platform { diff --git a/Telegram/SourceFiles/sysbuttons.cpp b/Telegram/SourceFiles/sysbuttons.cpp index 749bf2c55..1d2d4acb5 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 ea5609368..20f6c02da 100644 --- a/Telegram/SourceFiles/sysbuttons.h +++ b/Telegram/SourceFiles/sysbuttons.h @@ -68,7 +68,7 @@ protected: anim::cvalue a_color; Animation _a_color; - float64 _overLevel; + float64 _overLevel = 0.; QString _text; }; diff --git a/Telegram/SourceFiles/ui/style/style_core_icon.cpp b/Telegram/SourceFiles/ui/style/style_core_icon.cpp index 95445eb1b..3eb35a2b9 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) { From 4bdb2c48c78215c90c46af9ebbfab5c64845c074 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 1 Oct 2016 23:29:32 +0300 Subject: [PATCH 04/32] Replaced some exceptions in MTProto code with t_assert()s. --- Telegram/SourceFiles/mtproto/auth_key.h | 8 +- Telegram/SourceFiles/mtproto/core_types.h | 26 +- Telegram/SourceFiles/mtproto/generate.py | 14 +- Telegram/SourceFiles/mtproto/scheme_auto.h | 2162 ++++++++------------ 4 files changed, 824 insertions(+), 1386 deletions(-) diff --git a/Telegram/SourceFiles/mtproto/auth_key.h b/Telegram/SourceFiles/mtproto/auth_key.h index 935eee423..40dd3c6fb 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/core_types.h b/Telegram/SourceFiles/mtproto/core_types.h index e48a952be..f716ed230 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/generate.py b/Telegram/SourceFiles/mtproto/generate.py index aaa0ecc94..fabe2d5ca 100644 --- a/Telegram/SourceFiles/mtproto/generate.py +++ b/Telegram/SourceFiles/mtproto/generate.py @@ -22,7 +22,7 @@ import glob import re import binascii -# define some checked flag convertions +# define some checked flag conversions # the key flag type should be a subset of the value flag type # with exact the same names, then the key flag can be implicitly # casted to the value flag type @@ -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/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h index d72360477..5926b3997 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) { From 45dabbf9ab78371168bc23ab37616de6de3a534d Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 00:09:44 +0300 Subject: [PATCH 05/32] Replaced some exceptions in MTProto code with t_assert()s. --- Telegram/SourceFiles/mtproto/auth_key.h | 8 +- Telegram/SourceFiles/mtproto/core_types.h | 26 +- Telegram/SourceFiles/mtproto/generate.py | 14 +- Telegram/SourceFiles/mtproto/scheme_auto.h | 2162 ++++++++------------ 4 files changed, 824 insertions(+), 1386 deletions(-) diff --git a/Telegram/SourceFiles/mtproto/auth_key.h b/Telegram/SourceFiles/mtproto/auth_key.h index 935eee423..40dd3c6fb 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/core_types.h b/Telegram/SourceFiles/mtproto/core_types.h index e48a952be..f716ed230 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/generate.py b/Telegram/SourceFiles/mtproto/generate.py index aaa0ecc94..fabe2d5ca 100644 --- a/Telegram/SourceFiles/mtproto/generate.py +++ b/Telegram/SourceFiles/mtproto/generate.py @@ -22,7 +22,7 @@ import glob import re import binascii -# define some checked flag convertions +# define some checked flag conversions # the key flag type should be a subset of the value flag type # with exact the same names, then the key flag can be implicitly # casted to the value flag type @@ -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/scheme_auto.h b/Telegram/SourceFiles/mtproto/scheme_auto.h index d72360477..5926b3997 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) { From 1d6aba86ba28ab19dc2efc7638adcbc9ae73fdf4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 10:16:33 +0300 Subject: [PATCH 06/32] Removed channel name from first message. Fixed channel members count. --- Telegram/Resources/langs/lang.strings | 2 +- Telegram/SourceFiles/history/history_message.cpp | 2 +- Telegram/SourceFiles/profile/profile_cover.cpp | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 9573d6a0c..5c67fe279 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -567,7 +567,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}"; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index dc23b998d..5c15dc4f3 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -1808,7 +1808,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))); } diff --git a/Telegram/SourceFiles/profile/profile_cover.cpp b/Telegram/SourceFiles/profile/profile_cover.cpp index a30bc20be..76adaa96e 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(); } } From a41e0c4aa72fce0be358fdb8bcb7893f8eb07af2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 12:30:28 +0300 Subject: [PATCH 07/32] NB Broken! Started notification manager abstraction. --- Telegram/SourceFiles/application.cpp | 11 +- Telegram/SourceFiles/mainwindow.cpp | 348 ++---------------- Telegram/SourceFiles/mainwindow.h | 80 +--- .../platform/linux/main_window_linux.cpp | 4 +- .../platform/linux/main_window_linux.h | 10 +- .../linux/notifications_manager_linux.cpp | 38 ++ .../linux/notifications_manager_linux.h | 33 ++ .../platform/mac/main_window_mac.h | 10 +- .../platform/mac/main_window_mac.mm | 5 +- .../platform/mac/notifications_manager_mac.h | 33 ++ .../platform/mac/notifications_manager_mac.mm | 38 ++ .../platform/platform_notifications_manager.h | 31 ++ .../platform/win/main_window_win.cpp | 26 +- .../platform/win/main_window_win.h | 13 +- .../win/notifications_manager_win.cpp | 51 +++ .../platform/win/notifications_manager_win.h | 33 ++ .../platform/win/windows_toasts.cpp | 163 ++++---- .../SourceFiles/platform/win/windows_toasts.h | 20 +- Telegram/SourceFiles/pspecific_winrt.h | 6 +- .../settings_notifications_widget.cpp | 4 +- .../window/notifications_abstract_manager.cpp | 81 ++++ .../window/notifications_abstract_manager.h | 46 +++ .../window/notifications_default_manager.cpp | 327 ++++++++++++++++ .../window/notifications_default_manager.h | 98 +++++ Telegram/gyp/Telegram.gyp | 19 + Telegram/gyp/settings_win.gypi | 7 + 26 files changed, 1045 insertions(+), 490 deletions(-) create mode 100644 Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp create mode 100644 Telegram/SourceFiles/platform/linux/notifications_manager_linux.h create mode 100644 Telegram/SourceFiles/platform/mac/notifications_manager_mac.h create mode 100644 Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm create mode 100644 Telegram/SourceFiles/platform/platform_notifications_manager.h create mode 100644 Telegram/SourceFiles/platform/win/notifications_manager_win.cpp create mode 100644 Telegram/SourceFiles/platform/win/notifications_manager_win.h create mode 100644 Telegram/SourceFiles/window/notifications_abstract_manager.cpp create mode 100644 Telegram/SourceFiles/window/notifications_abstract_manager.h create mode 100644 Telegram/SourceFiles/window/notifications_default_manager.cpp create mode 100644 Telegram/SourceFiles/window/notifications_default_manager.h diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 9a21f66af..9ee03eee4 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -35,6 +35,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/observer.h" #include "observer_peer.h" #include "window/chat_background.h" +#include "window/notifications_abstract_manager.h" #include "history/history_location_manager.h" namespace { @@ -728,6 +729,7 @@ AppClass::AppClass() : QObject() style::startManager(); anim::startManager(); historyInit(); + Window::Notifications::start(); DEBUG_LOG(("Application Info: inited...")); @@ -741,7 +743,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(); @@ -1100,6 +1103,8 @@ AppClass::~AppClass() { auto window = createAndSwap(_window); delete window; + Window::Notifications::finish(); + anim::stopManager(); stopWebLoadManager(); @@ -1126,9 +1131,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/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index 43c59329e..f36b74141 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -43,6 +43,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" #include "apiwrap.h" #include "settings/settings_widget.h" +#include "window/notifications_default_manager.h" ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : QWidget(parent) , _shadow(st::boxShadow) @@ -81,289 +82,6 @@ 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); @@ -1440,8 +1158,8 @@ void MainWindow::notifyFire() { void MainWindow::notifyClear(History *history) { if (!history) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(); + for_const (auto widget, notifyWidgets) { + widget->unlinkHistory(); } psClearNotifies(); for (NotifyWhenMaps::const_iterator i = notifyWhenMaps.cbegin(), e = notifyWhenMaps.cend(); i != e; ++i) { @@ -1454,10 +1172,10 @@ void MainWindow::notifyClear(History *history) { } notifyWaiters.remove(history); notifySettingWaiters.remove(history); - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->unlinkHistory(history); + for_const (auto widget, notifyWidgets) { + widget->unlinkHistory(history); } - psClearNotifies(history->peer->id); + psClearNotifies(history); notifyWhenMaps.remove(history); notifyWhenAlerts.remove(history); notifyShowNext(); @@ -1466,11 +1184,11 @@ void MainWindow::notifyClear(History *history) { void MainWindow::notifyClearFast() { notifyWaiters.clear(); notifySettingWaiters.clear(); - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->deleteLater(); + for_const (auto widget, notifyWidgets) { + widget->deleteLater(); } psClearNotifies(); - notifyWindows.clear(); + notifyWidgets.clear(); notifyWhenMaps.clear(); notifyWhenAlerts.clear(); } @@ -1517,14 +1235,14 @@ void MainWindow::notifySettingGot() { notifyShowNext(); } -void MainWindow::notifyShowNext(NotifyWindow *remove) { +void MainWindow::notifyShowNext(Window::Notifications::Widget *remove) { if (App::quitting()) return; int32 count = NotifyWindowsCount; if (remove) { - for (NotifyWindows::iterator i = notifyWindows.begin(), e = notifyWindows.end(); i != e; ++i) { + for (auto i = notifyWidgets.begin(), e = notifyWidgets.end(); i != e; ++i) { if ((*i) == remove) { - notifyWindows.erase(i); + notifyWidgets.erase(i); break; } } @@ -1560,9 +1278,8 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; + for_const (auto widget, notifyWidgets) { + if (widget->index() < 0) continue; --count; } } @@ -1663,9 +1380,9 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } if (Global::CustomNotifies()) { - NotifyWindow *notify = new NotifyWindow(notifyItem, x, y, fwdCount); - notifyWindows.push_back(notify); - psNotifyShown(notify); + auto widget = new Window::Notifications::Widget(notifyItem, x, y, fwdCount); + notifyWidgets.push_back(widget); + psNotifyShown(widget); --count; } else { psPlatformNotify(notifyItem, fwdCount); @@ -1686,42 +1403,41 @@ void MainWindow::notifyShowNext(NotifyWindow *remove) { } count = NotifyWindowsCount - count; - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - int32 ind = (*i)->index(); - if (ind < 0) continue; + for_const (auto widget, notifyWidgets) { + if (widget->index() < 0) continue; --count; - (*i)->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); + widget->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); + for_const (auto widget, notifyWidgets) { + widget->itemRemoved(item); } } } void MainWindow::notifyStopHiding() { if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->stopHiding(); + for_const (auto widget, notifyWidgets) { + widget->stopHiding(); } } } void MainWindow::notifyStartHiding() { if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->startHiding(); + for_const (auto widget, notifyWidgets) { + widget->startHiding(); } } } void MainWindow::notifyUpdateAllPhotos() { if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - (*i)->updatePeerPhoto(); + for_const (auto widget, notifyWidgets) { + widget->updatePeerPhoto(); } } if (_mediaView && !_mediaView->isHidden()) _mediaView->updateControls(); @@ -1733,8 +1449,8 @@ 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(); + for_const (auto widget, notifyWidgets) { + widget->updateNotifyDisplay(); } } psClearNotifies(); @@ -1742,8 +1458,8 @@ void MainWindow::notifyUpdateAll() { void MainWindow::notifyActivateAll() { if (Global::CustomNotifies()) { - for (NotifyWindows::const_iterator i = notifyWindows.cbegin(), e = notifyWindows.cend(); i != e; ++i) { - psActivateNotify(*i); + for_const (auto widget, notifyWidgets) { + psActivateNotify(widget); } } } diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index c091e5e91..e35b12de1 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -32,28 +32,33 @@ class IntroWidget; class MainWidget; class LayerStackWidget; class LayerWidget; + namespace Local { class ClearManager; } // namespace Local + namespace Settings { class Widget; } // namespace Settings +namespace Window { +namespace Notifications { +class Widget; +} // namespace Notifications +} // namespace Window + 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: - Ui::RectShadow _shadow; QString _text; int32 _textWidth; @@ -61,69 +66,6 @@ private: }; -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 { @@ -208,7 +150,7 @@ public: void notifySchedule(History *history, HistoryItem *item); void notifyClear(History *history = 0); void notifyClearFast(); - void notifyShowNext(NotifyWindow *remove = 0); + void notifyShowNext(Window::Notifications::Widget *remove = 0); void notifyItemRemoved(HistoryItem *item); void notifyStopHiding(); void notifyStartHiding(); @@ -354,9 +296,11 @@ private: typedef QMap NotifyWhenAlerts; NotifyWhenAlerts notifyWhenAlerts; - NotifyWindows notifyWindows; + using NotifyWidgets = QList; + NotifyWidgets notifyWidgets; MediaView *_mediaView = nullptr; + }; class PreLaunchWindow : public TWidget { diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 2647ea36e..ff1fe33fc 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -663,13 +663,13 @@ void MainWindow::psUpdateMargins() { void MainWindow::psFlash() { } -void MainWindow::psActivateNotify(NotifyWindow *w) { +void MainWindow::psActivateNotify(Window::Notifications::Widget *w) { } void MainWindow::psClearNotifies(PeerId peerId) { } -void MainWindow::psNotifyShown(NotifyWindow *w) { +void MainWindow::psNotifyShown(Window::Notifications::Widget *w) { } void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index 2526a9c5f..e95acac1b 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -22,7 +22,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" -class NotifyWindow; +namespace Window { +namespace Notifications { +class Widget; +} // namespace Notifications +} // namespace Window namespace Platform { @@ -58,9 +62,9 @@ public: return posInited; } - void psActivateNotify(NotifyWindow *w); + void psActivateNotify(Window::Notifications::Widget *w); void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(NotifyWindow *w); + void psNotifyShown(Window::Notifications::Widget *w); void psPlatformNotify(HistoryItem *item, int32 fwdCount); void psUpdateCounter(); 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 000000000..c9d8a8562 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -0,0 +1,38 @@ +/* +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" + +namespace Platform { +namespace Notifications { + +void start() { +} + +Window::Notifications::AbstractManager *manager() { + return nullptr; +} + +void finish() { +} + +} // 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 000000000..71944652c --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -0,0 +1,33 @@ +/* +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_abstract_manager.h" + +namespace Platform { +namespace Notifications { + +void start(); +Window::Notifications::AbstractManager *manager(); +void finish(); + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 2bbe76dc4..e417aa187 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -23,7 +23,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" #include "pspecific_mac_p.h" -class NotifyWindow; +namespace Window { +namespace Notifications { +class Widget; +} // namespace Notifications +} // namespace Window namespace Platform { @@ -70,9 +74,9 @@ public: bool psFilterNativeEvent(void *event); - void psActivateNotify(NotifyWindow *w); + void psActivateNotify(Window::Notifications::Widget *w); void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(NotifyWindow *w); + void psNotifyShown(Window::Notifications::Widget *w); void psPlatformNotify(HistoryItem *item, int32 fwdCount); bool eventFilter(QObject *obj, QEvent *evt) override; diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 149e68803..8718b9c45 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "playerwidget.h" #include "historywidget.h" #include "localstorage.h" +#include "window/notifications_default_manager.h" #include "lang.h" @@ -467,7 +468,7 @@ void MainWindow::psClearNotifies(PeerId peerId) { _private.clearNotifies(peerId); } -void MainWindow::psActivateNotify(NotifyWindow *w) { +void MainWindow::psActivateNotify(Window::Notifications::Widget *w) { objc_activateWnd(w->winId()); } @@ -475,7 +476,7 @@ bool MainWindow::psFilterNativeEvent(void *event) { return _private.filterNativeEvent(event); } -void MainWindow::psNotifyShown(NotifyWindow *w) { +void MainWindow::psNotifyShown(Window::Notifications::Widget *w) { w->hide(); objc_holdOnTop(w->winId()); w->show(); 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 000000000..71944652c --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h @@ -0,0 +1,33 @@ +/* +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_abstract_manager.h" + +namespace Platform { +namespace Notifications { + +void start(); +Window::Notifications::AbstractManager *manager(); +void finish(); + +} // 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 000000000..45f9346db --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -0,0 +1,38 @@ +/* +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" + +namespace Platform { +namespace Notifications { + +void start() { +} + +Window::Notifications::AbstractManager *manager() { + return nullptr; +} + +void finish() { +} + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/platform_notifications_manager.h b/Telegram/SourceFiles/platform/platform_notifications_manager.h new file mode 100644 index 000000000..596d7f456 --- /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/winrt/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 343c5d4df..eb701532e 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "platform/win/windows_toasts.h" #include "platform/win/windows_dlls.h" +#include "window/notifications_abstract_manager.h" #include "mainwindow.h" #include "application.h" #include "lang.h" @@ -819,8 +820,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; @@ -1066,8 +1067,6 @@ MainWindow::~MainWindow() { if (taskbarList) taskbarList.Reset(); - Toasts::finish(); - _shadowsWorking = false; if (ps_menu) DestroyMenu(ps_menu); psDestroyIcons(); @@ -1075,23 +1074,22 @@ MainWindow::~MainWindow() { if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd); } -void MainWindow::psActivateNotify(NotifyWindow *w) { +void MainWindow::psActivateNotify(Window::Notifications::Widget *w) { } -void MainWindow::psClearNotifies(PeerId peerId) { - Toasts::clearNotifies(peerId); +void MainWindow::psClearNotifies(History *history) { + if (history) { + Window::Notifications::manager()->clearFromHistory(history); + } else { + Window::Notifications::manager()->clearAllFast(); + } } -void MainWindow::psNotifyShown(NotifyWindow *w) { +void MainWindow::psNotifyShown(Window::Notifications::Widget *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); + Window::Notifications::manager()->showNotification(item, fwdCount); } } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index 458788064..711d06ac4 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -23,9 +23,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" #include -class NotifyWindow; class PopupMenu; +namespace Window { +namespace Notifications { +class Widget; +} // namespace Notifications +} // namespace Window + namespace Platform { class MainWindow : public Window::MainWindow { @@ -62,9 +67,9 @@ public: return posInited; } - void psActivateNotify(NotifyWindow *w); - void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(NotifyWindow *w); + void psActivateNotify(Window::Notifications::Widget *w); + void psClearNotifies(History *history = nullptr); + void psNotifyShown(Window::Notifications::Widget *w); void psPlatformNotify(HistoryItem *item, int32 fwdCount); void psUpdateCounter(); diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp new file mode 100644 index 000000000..3e5e6f281 --- /dev/null +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -0,0 +1,51 @@ +/* +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/win/notifications_manager_win.h" + +#include "platform/win/windows_toasts.h" + +namespace Platform { +namespace Notifications { +namespace { + +NeverFreedPointer ToastsManager; + +} // namespace + +void start() { + Toasts::start(); +} + +Window::Notifications::AbstractManager *manager() { + if (Toasts::supported()) { + ToastsManager.makeIfNull(); + return ToastsManager.data(); + } + return nullptr; +} + +void finish() { + ToastsManager.reset(); +} + +} // 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 000000000..71944652c --- /dev/null +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h @@ -0,0 +1,33 @@ +/* +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_abstract_manager.h" + +namespace Platform { +namespace Notifications { + +void start(); +Window::Notifications::AbstractManager *manager(); +void finish(); + +} // namespace Notifications +} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.cpp b/Telegram/SourceFiles/platform/win/windows_toasts.cpp index 32ad7aa7e..ba952cb6f 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.cpp +++ b/Telegram/SourceFiles/platform/win/windows_toasts.cpp @@ -156,72 +156,6 @@ bool init() { 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; @@ -446,7 +380,87 @@ QString getImage(const StorageKey &key, PeerData *peer) { return i->path; } -bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, const QString &subtitle, const QString &msg) { +} // namespace + +void start() { + _supported = init(); +} + +void finish() { +} + +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; +} + +class Manager::Impl { +public: + bool create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + void clear(History *history, bool fast); + + ~Impl(); + +private: + +}; + +Manager::Impl::~Impl() { + _notifications.clear(); + if (_notificationManager) _notificationManager.Reset(); + if (_notifier) _notifier.Reset(); + if (_notificationFactory) _notificationFactory.Reset(); + + if (_imageSavedFlag) { + psDeleteDir(cWorkingDir() + qsl("tdata/temp")); + } +} + +void Manager::Impl::clear(History *history, bool fast) { + if (!_notifier) return; + + if (history) { + auto i = _notifications.find(history->peer->id); + 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()); + } + } + } +} + +bool Manager::Impl::create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { if (!supported() || !_notificationManager || !_notifier || !_notificationFactory) return false; ComPtr toastXml; @@ -460,7 +474,7 @@ bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, con StorageKey key; QString imagePath; - if (showpix) { + if (showUserpic) { key = peer->userpicUniqueKey(); } else { key = StorageKey(0, 0); @@ -549,5 +563,18 @@ bool create(PeerData *peer, int32 msgId, bool showpix, const QString &title, con return true; } +Manager::Manager() : _impl(std_::make_unique()) { +} + +Manager::~Manager() = default; + +void Manager::create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + _impl->create(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +} + +void Manager::clear(History *history, bool fast) { + return _impl->clear(history, fast); +} + } // namespace Toasts } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.h b/Telegram/SourceFiles/platform/win/windows_toasts.h index b271abc4c..a8cef3c1c 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.h +++ b/Telegram/SourceFiles/platform/win/windows_toasts.h @@ -20,19 +20,31 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "window/notifications_abstract_manager.h" + namespace Platform { namespace Toasts { void start(); -void finish(); - 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); +class Manager : public Window::Notifications::AbstractManager { +public: + Manager(); + + ~Manager(); + +private: + void create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + void clear(History *history, bool fast) override; + + class Impl; + std_::unique_ptr _impl; + +}; } // namespace Toasts } // namespace Platform diff --git a/Telegram/SourceFiles/pspecific_winrt.h b/Telegram/SourceFiles/pspecific_winrt.h index 06722c1ab..30ab755d5 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_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 86c34889c..82f175eb4 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -57,13 +57,13 @@ void NotificationsWidget::createControls() { _showSenderName->hideFast(); _showMessagePreview->hideFast(); } + addChildRow(_playSound, margin, lang(lng_settings_sound_notify), SLOT(onPlaySound()), Global::SoundNotify()); + addChildRow(_includeMuted, margin, lang(lng_settings_include_muted), SLOT(onIncludeMuted()), Global::IncludeMuted()); #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()); } void NotificationsWidget::onDesktopNotifications() { diff --git a/Telegram/SourceFiles/window/notifications_abstract_manager.cpp b/Telegram/SourceFiles/window/notifications_abstract_manager.cpp new file mode 100644 index 000000000..6ebd52d73 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_abstract_manager.cpp @@ -0,0 +1,81 @@ +/* +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_abstract_manager.h" + +#include "platform/platform_notifications_manager.h" +#include "window/notifications_default_manager.h" +#include "lang.h" + +namespace Window { +namespace Notifications { +namespace { + +NeverFreedPointer FallbackManager; + +} // namespace + +void start() { + Platform::Notifications::start(); +} + +AbstractManager *manager() { + if (auto result = Platform::Notifications::manager()) { + return result; + } + FallbackManager.makeIfNull(); + return FallbackManager.data(); +} + +void finish() { + Platform::Notifications::finish(); + FallbackManager.reset(); +} + +void AbstractManager::showNotification(HistoryItem *item, int forwardedCount) { + auto hideEverything = (App::passcoded() || Global::ScreenIsLocked()); + auto hideName = hideEverything || (Global::NotifyView() > dbinvShowName); + auto hidePreview = hideEverything || (Global::NotifyView() > dbinvShowPreview); + + QString title = hideName ? qsl("Telegram Desktop") : item->history()->peer->name; + QString subtitle = hideName ? QString() : item->notificationHeader(); + bool showUserpic = hideName ? false : true; + + QString msg = hidePreview ? lang(lng_notification_preview) : (forwardedCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, forwardedCount)); + bool showReplyButton = hidePreview ? false : item->history()->peer->canWrite(); + + create(item->history()->peer, item->id, title, subtitle, showUserpic, msg, showReplyButton); +} + +void AbstractManager::clearAllFast() { + clear(nullptr, true); +} + +void AbstractManager::clearAll() { + clear(nullptr, false); +} + +void AbstractManager::clearFromHistory(History *history) { + clear(history, false); +} + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_abstract_manager.h b/Telegram/SourceFiles/window/notifications_abstract_manager.h new file mode 100644 index 000000000..af8624114 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_abstract_manager.h @@ -0,0 +1,46 @@ +/* +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 AbstractManager; + +void start(); +AbstractManager *manager(); +void finish(); + +class AbstractManager { +public: + void showNotification(HistoryItem *item, int forwardedCount); + void clearAllFast(); + void clearAll(); + void clearFromHistory(History *history); + +private: + virtual void create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) = 0; + virtual void clear(History *history, bool fast) = 0; + +}; + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_default_manager.cpp b/Telegram/SourceFiles/window/notifications_default_manager.cpp new file mode 100644 index 000000000..1cedbcb7b --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_default_manager.cpp @@ -0,0 +1,327 @@ +/* +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_default_manager.h" + +#include "mainwindow.h" +#include "lang.h" +#include "dialogs/dialogs_layout.h" +#include "styles/style_dialogs.h" + +namespace Window { +namespace Notifications { + +void DefaultManager::create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { +} + +void DefaultManager::clear(History *history, bool fast) { +} + + +Widget::Widget(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, &Widget::step_appearance)) { + + updateNotifyDisplay(); + + hideTimer.setSingleShot(true); + connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); + + inputTimer.setSingleShot(true); + connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); + + close.setClickedCallback([this] { + 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 Widget::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 Widget::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 Widget::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 Widget::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 Widget::itemRemoved(HistoryItem *del) { + if (item == del) { + item = 0; + unlinkHistoryAndNotify(); + } +} + +void Widget::unlinkHistoryAndNotify() { + unlinkHistory(); + if (auto window = App::wnd()) { + window->notifyShowNext(); + } +} + +void Widget::unlinkHistory(History *hist) { + if (!hist || hist == history) { + animHide(st::notifyFastAnim, anim::linear); + history = 0; + item = 0; + } +} + +void Widget::enterEvent(QEvent *e) { + if (!history) return; + if (App::wnd()) App::wnd()->notifyStopHiding(); +} + +void Widget::leaveEvent(QEvent *e) { + if (!history) return; + App::wnd()->notifyStartHiding(); +} + +void Widget::startHiding() { + hideTimer.start(st::notifyWaitShortHide); +} + +void Widget::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 Widget::paintEvent(QPaintEvent *e) { + QPainter p(this); + p.drawPixmap(0, 0, pm); +} + +void Widget::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 Widget::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 Widget::hideByTimer() { + if (!history) return; + animHide(st::notifySlowHide, st::notifySlowHideFunc); +} + +void Widget::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(); +} + +Widget::~Widget() { + if (App::wnd()) App::wnd()->notifyShowNext(this); +} + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_default_manager.h b/Telegram/SourceFiles/window/notifications_default_manager.h new file mode 100644 index 000000000..19076d875 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_default_manager.h @@ -0,0 +1,98 @@ +/* +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_abstract_manager.h" + +namespace Window { +namespace Notifications { + +class DefaultManager : public AbstractManager { +public: + +private: + void create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + void clear(History *history, bool fast) override; + +}; + +class Widget : public TWidget { + Q_OBJECT + +public: + Widget(HistoryItem *item, int32 x, int32 y, int32 fwdCount); + + 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); + + ~Widget(); + +protected: + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void paintEvent(QPaintEvent *e) override; + +private slots: + void hideByTimer(); + void checkLastInput(); + +private: + void unlinkHistoryAndNotify(); + +#if defined Q_OS_WIN && !defined Q_OS_WINRT + uint64 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; + +}; + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 69abfe22a..09e1e0aa9 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -324,10 +324,16 @@ '<(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/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', @@ -336,6 +342,9 @@ '<(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', @@ -473,6 +482,10 @@ '<(src_loc)/window/chat_background.h', '<(src_loc)/window/main_window.cpp', '<(src_loc)/window/main_window.h', + '<(src_loc)/window/notifications_abstract_manager.cpp', + '<(src_loc)/window/notifications_abstract_manager.h', + '<(src_loc)/window/notifications_default_manager.cpp', + '<(src_loc)/window/notifications_default_manager.h', '<(src_loc)/window/section_widget.cpp', '<(src_loc)/window/section_widget.h', '<(src_loc)/window/slide_animation.cpp', @@ -501,6 +514,8 @@ '<(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"', { @@ -511,6 +526,8 @@ '<(src_loc)/pspecific_mac_p.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"', { @@ -526,6 +543,8 @@ '<(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', diff --git a/Telegram/gyp/settings_win.gypi b/Telegram/gyp/settings_win.gypi index b97a3d5fa..1d9f7b3b4 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', From 0bf55835f576c5c9fc7bc716ecc3e469c373aae7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 16:54:27 +0300 Subject: [PATCH 08/32] NB Broken! Notifications refactored to Manager, only Windows working. --- Telegram/SourceFiles/app.cpp | 11 +- Telegram/SourceFiles/application.cpp | 6 +- Telegram/SourceFiles/config.h | 2 - Telegram/SourceFiles/dialogswidget.cpp | 1 - Telegram/SourceFiles/facades.cpp | 2 - Telegram/SourceFiles/facades.h | 2 - Telegram/SourceFiles/history.cpp | 1 - Telegram/SourceFiles/history/history_item.cpp | 20 +- Telegram/SourceFiles/history/history_item.h | 6 +- Telegram/SourceFiles/localstorage.cpp | 3 - Telegram/SourceFiles/mainwindow.cpp | 201 ++++-------- Telegram/SourceFiles/mainwindow.h | 39 +-- Telegram/SourceFiles/mediaview.cpp | 6 + Telegram/SourceFiles/mediaview.h | 2 +- .../platform/linux/main_window_linux.cpp | 12 - .../platform/linux/main_window_linux.h | 11 - .../linux/notifications_manager_linux.cpp | 2 +- .../linux/notifications_manager_linux.h | 7 +- .../platform/mac/main_window_mac.h | 11 - .../platform/mac/main_window_mac.mm | 34 +- .../platform/mac/notifications_manager_mac.h | 21 +- .../platform/mac/notifications_manager_mac.mm | 87 ++++- .../platform/platform_file_dialog.h | 1 - .../platform/platform_notifications_manager.h | 2 +- .../platform/win/main_window_win.cpp | 45 +-- .../platform/win/main_window_win.h | 18 -- .../win/notifications_manager_win.cpp | 14 +- .../platform/win/notifications_manager_win.h | 7 +- .../platform/win/windows_toasts.cpp | 108 +++++-- .../SourceFiles/platform/win/windows_toasts.h | 21 +- Telegram/SourceFiles/pspecific_mac_p.h | 9 +- Telegram/SourceFiles/pspecific_mac_p.mm | 43 --- .../settings_notifications_widget.cpp | 6 +- .../window/notifications_abstract_manager.h | 46 --- ..._manager.cpp => notifications_manager.cpp} | 33 +- .../window/notifications_manager.h | 80 +++++ ....cpp => notifications_manager_default.cpp} | 299 +++++++++++++----- ...ager.h => notifications_manager_default.h} | 87 +++-- Telegram/gyp/Telegram.gyp | 8 +- 39 files changed, 702 insertions(+), 612 deletions(-) delete mode 100644 Telegram/SourceFiles/window/notifications_abstract_manager.h rename Telegram/SourceFiles/window/{notifications_abstract_manager.cpp => notifications_manager.cpp} (74%) create mode 100644 Telegram/SourceFiles/window/notifications_manager.h rename Telegram/SourceFiles/window/{notifications_default_manager.cpp => notifications_manager_default.cpp} (52%) rename Telegram/SourceFiles/window/{notifications_default_manager.h => notifications_manager_default.h} (50%) diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index 049b2a6ff..c9494f0a0 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; @@ -1992,13 +1993,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); @@ -2014,10 +2012,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 9ee03eee4..dc9014f69 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -35,7 +35,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/observer.h" #include "observer_peer.h" #include "window/chat_background.h" -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" #include "history/history_location_manager.h" namespace { @@ -333,6 +333,10 @@ void Application::closeApplication() { if (App::launchState() == App::QuitProcessed) return; App::setLaunchState(App::QuitProcessed); + if (auto manager = Window::Notifications::manager()) { + manager->clearAllFast(); + } + delete AppObject; AppObject = 0; diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index ab0ac7de7..a9b18db74 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -375,9 +375,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/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index b6b7dee00..3b94f1d27 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -479,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/facades.cpp b/Telegram/SourceFiles/facades.cpp index 69f133c6a..01e3c90fb 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -635,7 +635,6 @@ struct Data { bool IncludeMuted = true; DBINotifyView NotifyView = dbinvShowPreview; bool WindowsNotifications = true; - bool CustomNotifies = (cPlatform() == dbipMac) ? false : true; base::Observable NotifySettingsChanged; DBIConnectionType ConnectionType = dbictAuto; @@ -743,7 +742,6 @@ DefineVar(Global, bool, RestoreSoundNotifyFromTray); DefineVar(Global, bool, IncludeMuted); DefineVar(Global, DBINotifyView, NotifyView); DefineVar(Global, bool, WindowsNotifications); -DefineVar(Global, bool, CustomNotifies); DefineRefVar(Global, base::Observable, NotifySettingsChanged); DefineVar(Global, DBIConnectionType, ConnectionType); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 9c3e21f15..72d5699c2 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -149,7 +149,6 @@ enum class ChangeType { IncludeMuted, DesktopEnabled, ViewParams, - UseNative, }; } // namespace Notify @@ -309,7 +308,6 @@ DeclareVar(bool, RestoreSoundNotifyFromTray); DeclareVar(bool, IncludeMuted); DeclareVar(DBINotifyView, NotifyView); DeclareVar(bool, WindowsNotifications); -DeclareVar(bool, CustomNotifies); DeclareRefVar(base::Observable, NotifySettingsChanged); DeclareVar(DBIConnectionType, ConnectionType); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 5a97c9d85..057e34856 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/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 6b71261e3..15c856248 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -482,19 +482,19 @@ void HistoryMediaPtr::reset(HistoryMedia *p) { namespace internal { - TextSelection unshiftSelection(TextSelection selection, const Text &byText) { - if (selection == FullSelection) { - return selection; - } - return ::unshiftSelection(selection, byText); +TextSelection unshiftSelection(TextSelection selection, const Text &byText) { + if (selection == FullSelection) { + return selection; } + return ::unshiftSelection(selection, byText); +} - TextSelection shiftSelection(TextSelection selection, const Text &byText) { - if (selection == FullSelection) { - return selection; - } - return ::shiftSelection(selection, byText); +TextSelection shiftSelection(TextSelection selection, const Text &byText) { + if (selection == FullSelection) { + return selection; } + return ::shiftSelection(selection, byText); +} } // namespace internal diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 3be1f8665..1a8329ecc 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -436,8 +436,8 @@ private: namespace internal { - TextSelection unshiftSelection(TextSelection selection, const Text &byText); - TextSelection shiftSelection(TextSelection selection, const Text &byText); +TextSelection unshiftSelection(TextSelection selection, const Text &byText); +TextSelection shiftSelection(TextSelection selection, const Text &byText); } // namespace internal @@ -837,7 +837,7 @@ public: void clipCallback(Media::Clip::Notification notification); - virtual ~HistoryItem(); + ~HistoryItem(); protected: HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 5027ec7dc..19dc70dcf 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -995,9 +995,6 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) { if (!_checkStreamStatus(stream)) return false; Global::SetWindowsNotifications(v == 1); - if (cPlatform() == dbipWindows) { - Global::SetCustomNotifies((App::wnd() ? !App::wnd()->psHasNativeNotifications() : true) || !Global::WindowsNotifications()); - } } break; case dbiWorkMode: { diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index f36b74141..28abdf2af 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -43,7 +43,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "localstorage.h" #include "apiwrap.h" #include "settings/settings_widget.h" -#include "window/notifications_default_manager.h" +#include "window/notifications_manager.h" ConnectingWidget::ConnectingWidget(QWidget *parent, const QString &text, const QString &reconnect) : QWidget(parent) , _shadow(st::boxShadow) @@ -96,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(); } @@ -118,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); @@ -1130,72 +1127,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_const (auto widget, notifyWidgets) { - widget->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_const (auto widget, notifyWidgets) { - widget->unlinkHistory(history); - } - psClearNotifies(history); - 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_const (auto widget, notifyWidgets) { - widget->deleteLater(); - } - psClearNotifies(); - notifyWidgets.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) { @@ -1224,34 +1215,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(Window::Notifications::Widget *remove) { +void MainWindow::notifyShowNext() { if (App::quitting()) return; - int32 count = NotifyWindowsCount; - if (remove) { - for (auto i = notifyWidgets.begin(), e = notifyWidgets.end(); i != e; ++i) { - if ((*i) == remove) { - notifyWidgets.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 @@ -1264,7 +1245,7 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *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(); @@ -1277,32 +1258,24 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *remove) { App::playSound(); } - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - if (widget->index() < 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 { @@ -1316,8 +1289,8 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *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; @@ -1334,7 +1307,7 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *remove) { next = nextAlert; nextAlert = 0; } - notifyWaitTimer.start(next - ms); + _notifyWaitTimer.start(next - ms); break; } else { HistoryItem *fwd = notifyItem->Has() ? notifyItem : nullptr; // forwarded notify grouping @@ -1342,8 +1315,8 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *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; @@ -1358,7 +1331,7 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *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(); @@ -1379,18 +1352,11 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *remove) { } while (nextNotify); } - if (Global::CustomNotifies()) { - auto widget = new Window::Notifications::Widget(notifyItem, x, y, fwdCount); - notifyWidgets.push_back(widget); - psNotifyShown(widget); - --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; } } @@ -1399,48 +1365,8 @@ void MainWindow::notifyShowNext(Window::Notifications::Widget *remove) { } } if (nextAlert) { - notifyWaitTimer.start(nextAlert - ms); + _notifyWaitTimer.start(nextAlert - ms); } - - count = NotifyWindowsCount - count; - for_const (auto widget, notifyWidgets) { - if (widget->index() < 0) continue; - --count; - widget->moveTo(x, y - count * (st::notifyHeight + st::notifyDeltaY)); - } -} - -void MainWindow::notifyItemRemoved(HistoryItem *item) { - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - widget->itemRemoved(item); - } - } -} - -void MainWindow::notifyStopHiding() { - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - widget->stopHiding(); - } - } -} - -void MainWindow::notifyStartHiding() { - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - widget->startHiding(); - } - } -} - -void MainWindow::notifyUpdateAllPhotos() { - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - widget->updatePeerPhoto(); - } - } - if (_mediaView && !_mediaView->isHidden()) _mediaView->updateControls(); } void MainWindow::app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) { @@ -1448,20 +1374,7 @@ void MainWindow::app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButt } void MainWindow::notifyUpdateAll() { - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - widget->updateNotifyDisplay(); - } - } - psClearNotifies(); -} - -void MainWindow::notifyActivateAll() { - if (Global::CustomNotifies()) { - for_const (auto widget, notifyWidgets) { - psActivateNotify(widget); - } - } + Window::Notifications::manager()->updateAll(); } QImage MainWindow::iconLarge() const { diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index e35b12de1..9ace9c51d 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -43,7 +43,9 @@ class Widget; namespace Window { namespace Notifications { +namespace Default { class Widget; +} // namespace Default } // namespace Notifications } // namespace Window @@ -150,12 +152,7 @@ public: void notifySchedule(History *history, HistoryItem *item); void notifyClear(History *history = 0); void notifyClearFast(); - void notifyShowNext(Window::Notifications::Widget *remove = 0); - void notifyItemRemoved(HistoryItem *item); - void notifyStopHiding(); - void notifyStartHiding(); void notifyUpdateAll(); - void notifyActivateAll(); QImage iconLarge() const; @@ -212,7 +209,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(); @@ -224,8 +221,6 @@ public slots: void onReActivate(); - void notifyUpdateAllPhotos(); - void app_activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button); signals: @@ -277,27 +272,27 @@ 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; - - using NotifyWidgets = QList; - NotifyWidgets notifyWidgets; + using NotifyWhenAlert = QMap; + using NotifyWhenAlerts = QMap; + NotifyWhenAlerts _notifyWhenAlerts; MediaView *_mediaView = nullptr; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index cb086d89d..96216cbc6 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -97,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); diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index ae04b731f..809bec054 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -33,7 +33,7 @@ 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/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index ff1fe33fc..ecd15172c 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -663,18 +663,6 @@ void MainWindow::psUpdateMargins() { void MainWindow::psFlash() { } -void MainWindow::psActivateNotify(Window::Notifications::Widget *w) { -} - -void MainWindow::psClearNotifies(PeerId peerId) { -} - -void MainWindow::psNotifyShown(Window::Notifications::Widget *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 e95acac1b..739063177 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -22,12 +22,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" -namespace Window { -namespace Notifications { -class Widget; -} // namespace Notifications -} // namespace Window - namespace Platform { class MainWindow : public Window::MainWindow { @@ -62,11 +56,6 @@ public: return posInited; } - void psActivateNotify(Window::Notifications::Widget *w); - void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(Window::Notifications::Widget *w); - void psPlatformNotify(HistoryItem *item, int32 fwdCount); - void psUpdateCounter(); bool psHasNativeNotifications() { diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index c9d8a8562..ca680140b 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -27,7 +27,7 @@ namespace Notifications { void start() { } -Window::Notifications::AbstractManager *manager() { +Window::Notifications::Manager *manager() { return nullptr; } diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h index 71944652c..4478c9bad 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -20,14 +20,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" namespace Platform { namespace Notifications { void start(); -Window::Notifications::AbstractManager *manager(); +Window::Notifications::Manager *manager(); void finish(); +inline void defaultNotificationShown(QWidget *widget) { +} + } // namespace Notifications } // namespace Platform diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index e417aa187..434cb93ed 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -23,12 +23,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/main_window.h" #include "pspecific_mac_p.h" -namespace Window { -namespace Notifications { -class Widget; -} // namespace Notifications -} // namespace Window - namespace Platform { class MacPrivate : public PsMacWindowPrivate { @@ -74,11 +68,6 @@ public: bool psFilterNativeEvent(void *event); - void psActivateNotify(Window::Notifications::Widget *w); - void psClearNotifies(PeerId peerId = 0); - void psNotifyShown(Window::Notifications::Widget *w); - void psPlatformNotify(HistoryItem *item, int32 fwdCount); - bool eventFilter(QObject *obj, QEvent *evt) override; void psUpdateCounter(); diff --git a/Telegram/SourceFiles/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index 8718b9c45..08fa8495b 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "playerwidget.h" #include "historywidget.h" #include "localstorage.h" -#include "window/notifications_default_manager.h" +#include "window/notifications_manager_default.h" #include "lang.h" @@ -37,8 +37,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->enumerateWidgets([](QWidget *widget) { + objc_activateWnd(widget->winId()); + }); } } @@ -464,36 +466,10 @@ void MainWindow::psFlash() { _private.startBounce(); } -void MainWindow::psClearNotifies(PeerId peerId) { - _private.clearNotifies(peerId); -} - -void MainWindow::psActivateNotify(Window::Notifications::Widget *w) { - objc_activateWnd(w->winId()); -} - bool MainWindow::psFilterNativeEvent(void *event) { return _private.filterNativeEvent(event); } -void MainWindow::psNotifyShown(Window::Notifications::Widget *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 index 71944652c..3e4c67d94 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h @@ -20,14 +20,31 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" namespace Platform { namespace Notifications { void start(); -Window::Notifications::AbstractManager *manager(); +Window::Notifications::Manager *manager(); void finish(); +void defaultNotificationShown(QWidget *widget); + +class Manager : public Window::Notifications::NativeManager { +public: + Manager(); + ~Manager(); + +private: + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + void doClearAllFast() override; + void doClearFromHistory(History *history) override; + + 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 index 45f9346db..c62680ea2 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -21,18 +21,103 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "platform/mac/notifications_manager_mac.h" +#include "pspecific.h" + namespace Platform { namespace Notifications { void start() { } -Window::Notifications::AbstractManager *manager() { +Window::Notifications::Manager *manager() { return nullptr; } void finish() { } +void defaultNotificationShown(QWidget *widget) { + widget->hide(); + objc_holdOnTop(widget->winId()); + widget->show(); + psShowOverAll(w, false); +} + +class Manager::Impl { +public: + void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + void clearAll(); + void clearFromHistory(History *history); + + ~Impl(); + +private: + +}; + +void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + auto notification = [[NSUserNotification alloc] init]; + + [notification setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithUnsignedLongLong:peer->id],@"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 (showUserpic && [notification respondsToSelector:@selector(setContentImage:)]) { + auto userpic = peer->genUserpic(st::notifyMacPhotoSize); + auto img = qt_mac_create_nsimage(userpic); + [notification setContentImage:img]; + [img release]; + } + + if (showReplyButton && [notification respondsToSelector:@selector(setHasReplyButton:)]) { + [notification setHasReplyButton:YES]; + } + + [notification setSoundName:nil]; + + auto center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center deliverNotification:notification]; + + [notification release]; +} + +void Manager::Impl::clearAll() { + auto center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center removeAllDeliveredNotifications]; +} + +void Manager::Impl::clearFromHistory(History *history) { + unsigned long long peerId = history->peer->id; + + auto center = [NSUserNotificationCenter defaultUserNotificationCenter]; + auto notificationsList = [center deliveredNotifications]; + for (id notify in notificationsList) { + auto notifyUserInfo = [notify userInfo]; + auto notifyPeerId = [[notifyUserInfo objectForKey:@"peer"] unsignedLongLongValue]; + auto notifyLaunchId = [[notifyUserInfo objectForKey:@"launch"] unsignedLongLongValue]; + if (notifyPeerId == peerId && notifyLaunchId == Global::LaunchId()) { + [center removeDeliveredNotification:notify]; + } + } +} + +Manager::Manager() : _impl(std_::make_unique()) { +} + +Manager::~Manager() = default; + +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +} + +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 c3d91d84e..29bd064b8 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 index 596d7f456..81c10ae29 100644 --- a/Telegram/SourceFiles/platform/platform_notifications_manager.h +++ b/Telegram/SourceFiles/platform/platform_notifications_manager.h @@ -21,7 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #pragma once #ifdef Q_OS_MAC -#include "platform/winrt/notifications_manager_mac.h" +#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 diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index eb701532e..2003b23a9 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -23,7 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "platform/win/windows_toasts.h" #include "platform/win/windows_dlls.h" -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" #include "mainwindow.h" #include "application.h" #include "lang.h" @@ -617,7 +617,6 @@ MainWindow::MainWindow() if (!_taskbarCreatedMsgId) { _taskbarCreatedMsgId = RegisterWindowMessage(L"TaskbarButtonCreated"); } - connect(&ps_cleanNotifyPhotosTimer, SIGNAL(timeout()), this, SLOT(psCleanNotifyPhotos())); } void MainWindow::TaskbarCreated() { @@ -644,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)); @@ -879,17 +862,11 @@ void MainWindow::psUpdatedPosition() { } bool MainWindow::psHasNativeNotifications() { - return Toasts::supported(); + return (Toasts::manager() != nullptr); } Q_DECLARE_METATYPE(QMargins); void MainWindow::psFirstShow() { - if (Toasts::supported()) { - Global::SetCustomNotifies(!Global::WindowsNotifications()); - } else { - Global::SetCustomNotifies(true); - } - _psShadowWindows.init(_shActive); _shadowsWorking = true; @@ -1074,22 +1051,4 @@ MainWindow::~MainWindow() { if (ps_tbHider_hWnd) DestroyWindow(ps_tbHider_hWnd); } -void MainWindow::psActivateNotify(Window::Notifications::Widget *w) { -} - -void MainWindow::psClearNotifies(History *history) { - if (history) { - Window::Notifications::manager()->clearFromHistory(history); - } else { - Window::Notifications::manager()->clearAllFast(); - } -} - -void MainWindow::psNotifyShown(Window::Notifications::Widget *w) { -} - -void MainWindow::psPlatformNotify(HistoryItem *item, int32 fwdCount) { - Window::Notifications::manager()->showNotification(item, fwdCount); -} - } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index 711d06ac4..cd16f71d6 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -25,12 +25,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org class PopupMenu; -namespace Window { -namespace Notifications { -class Widget; -} // namespace Notifications -} // namespace Window - namespace Platform { class MainWindow : public Window::MainWindow { @@ -67,15 +61,9 @@ public: return posInited; } - void psActivateNotify(Window::Notifications::Widget *w); - void psClearNotifies(History *history = nullptr); - void psNotifyShown(Window::Notifications::Widget *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; @@ -111,15 +99,11 @@ public: ~MainWindow(); public slots: - void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psShowTrayMenu(); - void psCleanNotifyPhotos(); - protected: - bool psHasTrayIcon() const { return trayIcon; } @@ -150,8 +134,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/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 3e5e6f281..7f1066ac3 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -25,26 +25,20 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Platform { namespace Notifications { -namespace { - -NeverFreedPointer ToastsManager; - -} // namespace void start() { Toasts::start(); } -Window::Notifications::AbstractManager *manager() { - if (Toasts::supported()) { - ToastsManager.makeIfNull(); - return ToastsManager.data(); +Window::Notifications::Manager *manager() { + if (Global::WindowsNotifications()) { + return Toasts::manager(); } return nullptr; } void finish() { - ToastsManager.reset(); + Toasts::finish(); } } // namespace Notifications diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.h b/Telegram/SourceFiles/platform/win/notifications_manager_win.h index 71944652c..4478c9bad 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.h +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h @@ -20,14 +20,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" namespace Platform { namespace Notifications { void start(); -Window::Notifications::AbstractManager *manager(); +Window::Notifications::Manager *manager(); void finish(); +inline void defaultNotificationShown(QWidget *widget) { +} + } // namespace Notifications } // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.cpp b/Telegram/SourceFiles/platform/win/windows_toasts.cpp index ba952cb6f..c27db8f74 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.cpp +++ b/Telegram/SourceFiles/platform/win/windows_toasts.cpp @@ -47,7 +47,10 @@ namespace Platform { namespace Toasts { namespace { -bool _supported = false; +// Delete notify photo file after 1 minute of not using. +constexpr int kNotifyDeletePhotoAfterMs = 60000; + +NeverFreedPointer ToastsManager; ComPtr _notificationManager; ComPtr _notifier; @@ -357,14 +360,18 @@ QString getImage(const StorageKey &key, PeerData *peer) { auto i = _images.find(key); if (i != _images.cend()) { if (i->until) { - i->until = ms + NotifyDeletePhotoAfter; - if (App::wnd()) App::wnd()->psCleanNotifyPhotosIn(-NotifyDeletePhotoAfter); + i->until = ms + kNotifyDeletePhotoAfterMs; + if (auto manager = ToastsManager.data()) { + manager->clearNotifyPhotosInMs(-kNotifyDeletePhotoAfterMs); + } } } else { Image v; if (key.first) { - v.until = ms + NotifyDeletePhotoAfter; - if (App::wnd()) App::wnd()->psCleanNotifyPhotosIn(-NotifyDeletePhotoAfter); + v.until = ms + kNotifyDeletePhotoAfterMs; + if (auto manager = ToastsManager.data()) { + manager->clearNotifyPhotosInMs(-kNotifyDeletePhotoAfterMs); + } } else { v.until = 0; } @@ -383,14 +390,17 @@ QString getImage(const StorageKey &key, PeerData *peer) { } // namespace void start() { - _supported = init(); + if (init()) { + ToastsManager.makeIfNull(); + } +} + +Manager *manager() { + return ToastsManager.data(); } void finish() { -} - -bool supported() { - return _supported; + ToastsManager.reset(); } uint64 clearImages(uint64 ms) { @@ -417,12 +427,15 @@ uint64 clearImages(uint64 ms) { class Manager::Impl { public: - bool create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); - void clear(History *history, bool fast); + bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + void clearAll(); + void clearFromHistory(History *history); ~Impl(); private: + QTimer _clearNotifyPhotosTimer; + friend class Manager; }; @@ -437,31 +450,33 @@ Manager::Impl::~Impl() { } } -void Manager::Impl::clear(History *history, bool fast) { +void Manager::Impl::clearAll() { if (!_notifier) return; - if (history) { - auto i = _notifications.find(history->peer->id); - 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()); - } + auto temp = createAndSwap(_notifications); + for_const (auto ¬ifications, temp) { + for_const (auto ¬ification, notifications) { + _notifier->Hide(notification.p.Get()); } } } -bool Manager::Impl::create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - if (!supported() || !_notificationManager || !_notifier || !_notificationFactory) return false; +void Manager::Impl::clearFromHistory(History *history) { + if (!_notifier) return; + + auto i = _notifications.find(history->peer->id); + 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()); + } + } +} + +bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + if (!_notificationManager || !_notifier || !_notificationFactory) return false; ComPtr toastXml; bool withSubtitle = !subtitle.isEmpty(); @@ -564,16 +579,39 @@ bool Manager::Impl::create(PeerData *peer, MsgId msgId, const QString &title, co } Manager::Manager() : _impl(std_::make_unique()) { + connect(&_impl->_clearNotifyPhotosTimer, SIGNAL(timeout()), this, SLOT(onClearNotifyPhotos())); +} + +void Manager::clearNotifyPhotosInMs(int ms) { + if (ms < 0) { + ms = -ms; + if (_impl->_clearNotifyPhotosTimer.isActive() && _impl->_clearNotifyPhotosTimer.remainingTime() <= ms) { + return; + } + } + _impl->_clearNotifyPhotosTimer.start(ms); +} + +void Manager::onClearNotifyPhotos() { + auto ms = getms(true); + auto minuntil = Toasts::clearImages(ms); + if (minuntil) { + clearNotifyPhotosInMs(int32(minuntil - ms)); + } } Manager::~Manager() = default; -void Manager::create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - _impl->create(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); } -void Manager::clear(History *history, bool fast) { - return _impl->clear(history, fast); +void Manager::doClearAllFast() { + _impl->clearAll(); +} + +void Manager::doClearFromHistory(History *history) { + _impl->clearFromHistory(history); } } // namespace Toasts diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.h b/Telegram/SourceFiles/platform/win/windows_toasts.h index a8cef3c1c..517f4aedc 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.h +++ b/Telegram/SourceFiles/platform/win/windows_toasts.h @@ -20,26 +20,37 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" namespace Platform { namespace Toasts { +class Manager; + void start(); -bool supported(); +Manager *manager(); +void finish(); // Returns the next ms when clearImages() should be called. uint64 clearImages(uint64 ms); -class Manager : public Window::Notifications::AbstractManager { +class Manager : public QObject, public Window::Notifications::NativeManager { + Q_OBJECT + public: Manager(); + void clearNotifyPhotosInMs(int ms); + ~Manager(); +private slots: + void onClearNotifyPhotos(); + private: - void create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; - void clear(History *history, bool fast) override; + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + void doClearAllFast() override; + void doClearFromHistory(History *history) override; class Impl; std_::unique_ptr _impl; diff --git a/Telegram/SourceFiles/pspecific_mac_p.h b/Telegram/SourceFiles/pspecific_mac_p.h index 2cd3098e2..b186e28c1 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 */ @@ -29,9 +29,6 @@ public: 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); diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 9f538d74f..16a2917c9 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -293,33 +293,6 @@ void objc_activateWnd(WId winId) { 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]; -} - void PsMacWindowPrivate::enableShadow(WId winId) { // [[(NSView*)winId window] setStyleMask:NSBorderlessWindowMask]; // [[(NSView*)winId window] setHasShadow:YES]; @@ -359,22 +332,6 @@ 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]; } diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 82f175eb4..6dd4b8f93 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -27,6 +27,7 @@ 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" namespace Settings { @@ -132,16 +133,13 @@ void NotificationsWidget::viewParamUpdated() { } void NotificationsWidget::onWindowsNative() { -#ifdef Q_OS_WIN if (Global::WindowsNotifications() == _windowsNative->checked()) { return; } + Window::Notifications::manager()->clearAllFast(); Global::SetWindowsNotifications(_windowsNative->checked()); - Global::SetCustomNotifies(!Global::WindowsNotifications()); Local::writeUserSettings(); - Global::RefNotifySettingsChanged().notify(Notify::ChangeType::UseNative); -#endif // Q_OS_WIN } void NotificationsWidget::onPlaySound() { diff --git a/Telegram/SourceFiles/window/notifications_abstract_manager.h b/Telegram/SourceFiles/window/notifications_abstract_manager.h deleted file mode 100644 index af8624114..000000000 --- a/Telegram/SourceFiles/window/notifications_abstract_manager.h +++ /dev/null @@ -1,46 +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 -*/ -#pragma once - -namespace Window { -namespace Notifications { - -class AbstractManager; - -void start(); -AbstractManager *manager(); -void finish(); - -class AbstractManager { -public: - void showNotification(HistoryItem *item, int forwardedCount); - void clearAllFast(); - void clearAll(); - void clearFromHistory(History *history); - -private: - virtual void create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) = 0; - virtual void clear(History *history, bool fast) = 0; - -}; - -} // namespace Notifications -} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_abstract_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp similarity index 74% rename from Telegram/SourceFiles/window/notifications_abstract_manager.cpp rename to Telegram/SourceFiles/window/notifications_manager.cpp index 6ebd52d73..ac05db88e 100644 --- a/Telegram/SourceFiles/window/notifications_abstract_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -19,38 +19,33 @@ 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_abstract_manager.h" +#include "window/notifications_manager.h" #include "platform/platform_notifications_manager.h" -#include "window/notifications_default_manager.h" +#include "window/notifications_manager_default.h" #include "lang.h" namespace Window { namespace Notifications { -namespace { - -NeverFreedPointer FallbackManager; - -} // namespace void start() { + Default::start(); Platform::Notifications::start(); } -AbstractManager *manager() { +Manager *manager() { if (auto result = Platform::Notifications::manager()) { return result; } - FallbackManager.makeIfNull(); - return FallbackManager.data(); + return Default::manager(); } void finish() { Platform::Notifications::finish(); - FallbackManager.reset(); + Default::finish(); } -void AbstractManager::showNotification(HistoryItem *item, int forwardedCount) { +void NativeManager::doShowNotification(HistoryItem *item, int forwardedCount) { auto hideEverything = (App::passcoded() || Global::ScreenIsLocked()); auto hideName = hideEverything || (Global::NotifyView() > dbinvShowName); auto hidePreview = hideEverything || (Global::NotifyView() > dbinvShowPreview); @@ -62,19 +57,7 @@ void AbstractManager::showNotification(HistoryItem *item, int forwardedCount) { QString msg = hidePreview ? lang(lng_notification_preview) : (forwardedCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, forwardedCount)); bool showReplyButton = hidePreview ? false : item->history()->peer->canWrite(); - create(item->history()->peer, item->id, title, subtitle, showUserpic, msg, showReplyButton); -} - -void AbstractManager::clearAllFast() { - clear(nullptr, true); -} - -void AbstractManager::clearAll() { - clear(nullptr, false); -} - -void AbstractManager::clearFromHistory(History *history) { - clear(history, false); + doShowNativeNotification(item->history()->peer, item->id, title, subtitle, showUserpic, msg, showReplyButton); } } // namespace Notifications diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h new file mode 100644 index 000000000..5048b07d8 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -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 +*/ +#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); + } + +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; + +}; + +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, bool showUserpic, const QString &msg, bool showReplyButton) = 0; + +}; + +} // namespace Notifications +} // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_default_manager.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp similarity index 52% rename from Telegram/SourceFiles/window/notifications_default_manager.cpp rename to Telegram/SourceFiles/window/notifications_manager_default.cpp index 1cedbcb7b..ecd458b4f 100644 --- a/Telegram/SourceFiles/window/notifications_default_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.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 "window/notifications_default_manager.h" +#include "window/notifications_manager_default.h" +#include "platform/platform_notifications_manager.h" #include "mainwindow.h" #include "lang.h" #include "dialogs/dialogs_layout.h" @@ -28,45 +29,174 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Window { namespace Notifications { +namespace Default { +namespace { -void DefaultManager::create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { +// 3 desktop notifies at the same time. +constexpr int kNotifyWindowsCount = 3; + +NeverFreedPointer FallbackManager; + +} // namespace + +void start() { + FallbackManager.makeIfNull(); } -void DefaultManager::clear(History *history, bool fast) { +Manager *manager() { + return FallbackManager.data(); } +void finish() { + FallbackManager.reset(); +} -Widget::Widget(HistoryItem *msg, int32 x, int32 y, int32 fwdCount) : TWidget(0) -, history(msg->history()) -, item(msg) -, fwdCount(fwdCount) +Manager::Manager() { + subscribe(FileDownload::ImageLoaded(), [this] { + for_const (auto widget, _widgets) { + widget->updatePeerPhoto(); + } + }); +} + +void Manager::startAllHiding() { + for_const (auto widget, _widgets) { + widget->startHiding(); + } +} + +void Manager::stopAllHiding() { + for_const (auto widget, _widgets) { + widget->stopHiding(); + } +} + +void Manager::showNextFromQueue() { + if (_queuedNotifications.isEmpty()) { + return; + } + + int count = kNotifyWindowsCount; + for_const (auto widget, _widgets) { + if (widget->index() < 0) continue; + --count; + } + if (count <= 0) { + return; + } + + auto r = psDesktopRect(); + auto x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX; + auto y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY; + do { + auto queued = _queuedNotifications.front(); + _queuedNotifications.pop_front(); + + auto widget = std_::make_unique(queued.history, queued.peer, queued.author, queued.item, queued.forwardedCount, x, y); + Platform::Notifications::defaultNotificationShown(widget.get()); + _widgets.push_back(widget.release()); + --count; + } while (count > 0 && !_queuedNotifications.isEmpty()); + + auto shown = kNotifyWindowsCount - count; + for_const (auto widget, _widgets) { + if (widget->index() < 0) continue; + --shown; + widget->moveTo(x, y - shown * (st::notifyHeight + st::notifyDeltaY)); + } +} + +void Manager::removeFromShown(Widget *remove) { + if (remove) { + auto index = _widgets.indexOf(remove); + if (index >= 0) { + _widgets.removeAt(index); + } + } + showNextFromQueue(); +} + +void Manager::doShowNotification(HistoryItem *item, int forwardedCount) { + _queuedNotifications.push_back(QueuedNotification(item, forwardedCount)); + showNextFromQueue(); +} + +void Manager::doClearAll() { + _queuedNotifications.clear(); + for_const (auto widget, _widgets) { + widget->unlinkHistory(); + } +} + +void Manager::doClearAllFast() { + _queuedNotifications.clear(); + + auto widgets = createAndSwap(_widgets); + for_const (auto widget, widgets) { + widget->deleteLater(); + } +} + +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 widget, _widgets) { + widget->unlinkHistory(history); + } + showNextFromQueue(); +} + +void Manager::doClearFromItem(HistoryItem *item) { + for_const (auto widget, _widgets) { + widget->itemRemoved(item); + } +} + +void Manager::doUpdateAll() { + for_const (auto widget, _widgets) { + widget->updateNotifyDisplay(); + } +} + +Manager::~Manager() { + clearAllFast(); +} + +Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *msg, int forwardedCount, int x, int y) : TWidget(nullptr) +, _history(history) +, _peer(peer) +, _author(author) +, _item(msg) +, _forwardedCount(forwardedCount) #if defined Q_OS_WIN && !defined Q_OS_WINRT -, started(GetTickCount()) +, _started(GetTickCount()) #endif // Q_OS_WIN && !Q_OS_WINRT -, close(this, st::notifyClose) -, alphaDuration(st::notifyFastAnim) -, posDuration(st::notifyFastAnim) -, hiding(false) -, _index(0) +, _close(this, st::notifyClose) +, _alphaDuration(st::notifyFastAnim) +, _posDuration(st::notifyFastAnim) , a_opacity(0) , a_func(anim::linear) , a_y(y + st::notifyHeight + st::notifyDeltaY) , _a_appearance(animation(this, &Widget::step_appearance)) { - updateNotifyDisplay(); - hideTimer.setSingleShot(true); - connect(&hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); + _hideTimer.setSingleShot(true); + connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); - inputTimer.setSingleShot(true); - connect(&inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); + _inputTimer.setSingleShot(true); + connect(&_inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); - close.setClickedCallback([this] { + _close.setClickedCallback([this] { unlinkHistoryAndNotify(); }); - close.setAcceptBoth(true); - close.move(st::notifyWidth - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); - close.show(); + _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); @@ -79,7 +209,7 @@ Widget::Widget(HistoryItem *msg, int32 x, int32 y, int32 fwdCount) : TWidget(0) setWindowOpacity(a_opacity.current()); - alphaDuration = posDuration = st::notifyFastAnim; + _alphaDuration = _posDuration = st::notifyFastAnim; _a_appearance.start(); checkLastInput(); @@ -90,34 +220,34 @@ void Widget::checkLastInput() { LASTINPUTINFO lii; lii.cbSize = sizeof(LASTINPUTINFO); BOOL res = GetLastInputInfo(&lii); - if (!res || lii.dwTime >= started) { - hideTimer.start(st::notifyWaitLongHide); + if (!res || lii.dwTime >= _started) { + _hideTimer.start(st::notifyWaitLongHide); } else { - inputTimer.start(300); + _inputTimer.start(300); } #else // Q_OS_WIN && !Q_OS_WINRT // TODO if (true) { - hideTimer.start(st::notifyWaitLongHide); + _hideTimer.start(st::notifyWaitLongHide); } else { - inputTimer.start(300); + _inputTimer.start(300); } #endif // else for Q_OS_WIN && !Q_OS_WINRT } -void Widget::moveTo(int32 x, int32 y, int32 index) { +void Widget::moveTo(int x, int y, int index) { if (index >= 0) { _index = index; } move(x, a_y.current()); a_y.start(y); a_opacity.restart(); - posDuration = st::notifyFastAnim; + _posDuration = st::notifyFastAnim; _a_appearance.start(); } void Widget::updateNotifyDisplay() { - if (!item) return; + if (!_history || !_peer || (!_item && _forwardedCount < 2)) return; int32 w = st::notifyWidth, h = st::notifyHeight; QImage img(w * cIntRetinaFactor(), h * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); @@ -132,8 +262,8 @@ void Widget::updateNotifyDisplay() { 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()); + _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); @@ -143,113 +273,109 @@ void Widget::updateNotifyDisplay() { 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)) { + 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) { + if (_item) { bool active = false; - item->drawInDialog(p, r, active, textCachedFor, itemTextCache); - } else { + _item->drawInDialog(p, r, active, textCachedFor, itemTextCache); + } else if (_forwardedCount > 1) { p.setFont(st::dialogsTextFont); - if (item->hasFromName() && !item->isPost()) { - itemTextCache.setText(st::dialogsTextFont, item->author()->name); + 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, fwdCount)); + 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 (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { - history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); + _history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } else { - p.setFont(st::msgNameFont->f); + 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); } } - pm = App::pixmapFromImageInPlace(std_::move(img)); + _cache = App::pixmapFromImageInPlace(std_::move(img)); update(); } void Widget::updatePeerPhoto() { if (!peerPhoto->isNull() && peerPhoto->loaded()) { - QImage img(pm.toImage()); + auto img = _cache.toImage(); { - QPainter p(&img); + Painter p(&img); p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); } peerPhoto = ImagePtr(); - pm = App::pixmapFromImageInPlace(std_::move(img)); + _cache = App::pixmapFromImageInPlace(std_::move(img)); update(); } } -void Widget::itemRemoved(HistoryItem *del) { - if (item == del) { - item = 0; +void Widget::itemRemoved(HistoryItem *deleted) { + if (_item && _item == deleted) { + _item = nullptr; unlinkHistoryAndNotify(); } } void Widget::unlinkHistoryAndNotify() { unlinkHistory(); - if (auto window = App::wnd()) { - window->notifyShowNext(); + if (auto manager = FallbackManager.data()) { + manager->showNextFromQueue(); } } -void Widget::unlinkHistory(History *hist) { - if (!hist || hist == history) { +void Widget::unlinkHistory(History *history) { + if (!history || history == _history) { animHide(st::notifyFastAnim, anim::linear); - history = 0; - item = 0; + _history = nullptr; + _item = nullptr; } } void Widget::enterEvent(QEvent *e) { - if (!history) return; - if (App::wnd()) App::wnd()->notifyStopHiding(); + if (!_history) return; + if (auto manager = FallbackManager.data()) { + manager->stopAllHiding(); + } } void Widget::leaveEvent(QEvent *e) { - if (!history) return; - App::wnd()->notifyStartHiding(); + if (!_history) return; + if (auto manager = FallbackManager.data()) { + manager->startAllHiding(); + } } void Widget::startHiding() { - hideTimer.start(st::notifyWaitShortHide); + _hideTimer.start(st::notifyWaitShortHide); } void Widget::mousePressEvent(QMouseEvent *e) { - if (!history) return; + if (!_history) return; - PeerId peer = history->peer->id; - MsgId msgId = (!history->peer->isUser() && item && item->mentionsMe() && item->id > 0) ? item->id : ShowAtUnreadMsgId; + auto peerId = _history->peer->id; + auto msgId = (!_history->peer->isUser() && _item && _item->mentionsMe() && _item->id > 0) ? _item->id : ShowAtUnreadMsgId; if (e->button() == Qt::RightButton) { unlinkHistoryAndNotify(); @@ -259,7 +385,7 @@ void Widget::mousePressEvent(QMouseEvent *e) { App::wnd()->setInnerFocus(); App::wnd()->notifyClear(); } else { - Ui::showPeerHistory(peer, msgId); + Ui::showPeerHistory(peerId, msgId); } e->ignore(); } @@ -267,40 +393,40 @@ void Widget::mousePressEvent(QMouseEvent *e) { void Widget::paintEvent(QPaintEvent *e) { QPainter p(this); - p.drawPixmap(0, 0, pm); + p.drawPixmap(0, 0, _cache); } void Widget::animHide(float64 duration, anim::transition func) { - if (!history) return; - alphaDuration = duration; + if (!_history) return; + _alphaDuration = duration; a_func = func; a_opacity.start(0); a_y.restart(); - hiding = true; + _hiding = true; _a_appearance.start(); } void Widget::stopHiding() { - if (!history) return; - alphaDuration = st::notifyFastAnim; + if (!_history) return; + _alphaDuration = st::notifyFastAnim; a_func = anim::linear; a_opacity.start(1); a_y.restart(); - hiding = false; - hideTimer.stop(); + _hiding = false; + _hideTimer.stop(); _a_appearance.start(); } void Widget::hideByTimer() { - if (!history) return; + if (!_history) return; animHide(st::notifySlowHide, st::notifySlowHideFunc); } void Widget::step_appearance(float64 ms, bool timer) { - float64 dtAlpha = ms / alphaDuration, dtPos = ms / posDuration; + float64 dtAlpha = ms / _alphaDuration, dtPos = ms / _posDuration; if (dtAlpha >= 1) { a_opacity.finish(); - if (hiding) { + if (_hiding) { _a_appearance.stop(); deleteLater(); } else if (dtPos >= 1) { @@ -320,8 +446,11 @@ void Widget::step_appearance(float64 ms, bool timer) { } Widget::~Widget() { - if (App::wnd()) App::wnd()->notifyShowNext(this); + if (auto manager = FallbackManager.data()) { + manager->removeFromShown(this); + } } +} // namespace Default } // namespace Notifications } // namespace Window diff --git a/Telegram/SourceFiles/window/notifications_default_manager.h b/Telegram/SourceFiles/window/notifications_manager_default.h similarity index 50% rename from Telegram/SourceFiles/window/notifications_default_manager.h rename to Telegram/SourceFiles/window/notifications_manager_default.h index 19076d875..bb1fd8789 100644 --- a/Telegram/SourceFiles/window/notifications_default_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -20,17 +20,65 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "window/notifications_abstract_manager.h" +#include "window/notifications_manager.h" namespace Window { namespace Notifications { +namespace Default { -class DefaultManager : public AbstractManager { +class Manager; +class Widget; + +void start(); +Manager *manager(); +void finish(); + +class Manager : public Notifications::Manager, private base::Subscriber { public: + Manager(); + + void showNextFromQueue(); + void removeFromShown(Widget *remove); + void startAllHiding(); + void stopAllHiding(); + + template + void enumerateWidgets(Method method) { + for_const (auto widget, _widgets) { + method(widget); + } + } + + ~Manager(); private: - void create(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; - void clear(History *history, bool fast) override; + 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; + + using Widgets = QList; + Widgets _widgets; + + 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; }; @@ -38,21 +86,21 @@ class Widget : public TWidget { Q_OBJECT public: - Widget(HistoryItem *item, int32 x, int32 y, int32 fwdCount); + Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, int x, int y); 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 moveTo(int x, int y, int index = -1); void updateNotifyDisplay(); void updatePeerPhoto(); void itemRemoved(HistoryItem *del); - int32 index() const { - return history ? _index : -1; + int index() const { + return _history ? _index : -1; } void unlinkHistory(History *hist = 0); @@ -73,18 +121,20 @@ private: void unlinkHistoryAndNotify(); #if defined Q_OS_WIN && !defined Q_OS_WINRT - uint64 started; + uint64 _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; + History *_history; + PeerData *_peer; + PeerData *_author; + HistoryItem *_item; + int _forwardedCount; + IconedButton _close; + QPixmap _cache; + float64 _alphaDuration, _posDuration; + QTimer _hideTimer, _inputTimer; + bool _hiding = false; + int _index = 0; anim::fvalue a_opacity; anim::transition a_func; anim::ivalue a_y; @@ -94,5 +144,6 @@ private: }; +} // namespace Default } // namespace Notifications } // namespace Window diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 09e1e0aa9..6531e52a0 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -482,10 +482,10 @@ '<(src_loc)/window/chat_background.h', '<(src_loc)/window/main_window.cpp', '<(src_loc)/window/main_window.h', - '<(src_loc)/window/notifications_abstract_manager.cpp', - '<(src_loc)/window/notifications_abstract_manager.h', - '<(src_loc)/window/notifications_default_manager.cpp', - '<(src_loc)/window/notifications_default_manager.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/section_widget.cpp', '<(src_loc)/window/section_widget.h', '<(src_loc)/window/slide_animation.cpp', From c2aa8d3c77993e1b7f73bf9ba65a7cbdc225bf74 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 18:44:54 +0300 Subject: [PATCH 09/32] NB Broken! Build in Xcode fixed, macOS notifications done by Manager. --- .../SourceFiles/platform/mac/mac_utilities.h | 39 + .../SourceFiles/platform/mac/mac_utilities.mm | 19 + .../platform/mac/notifications_manager_mac.mm | 58 +- .../platform/win/windows_toasts.cpp | 12 +- Telegram/SourceFiles/pspecific_mac_p.mm | 736 +++++++++--------- .../window/notifications_manager.h | 1 + .../window/notifications_manager_default.cpp | 16 +- Telegram/gyp/Telegram.gyp | 4 + 8 files changed, 508 insertions(+), 377 deletions(-) create mode 100644 Telegram/SourceFiles/platform/mac/mac_utilities.h create mode 100644 Telegram/SourceFiles/platform/mac/mac_utilities.mm diff --git a/Telegram/SourceFiles/platform/mac/mac_utilities.h b/Telegram/SourceFiles/platform/mac/mac_utilities.h new file mode 100644 index 000000000..692cd43d1 --- /dev/null +++ b/Telegram/SourceFiles/platform/mac/mac_utilities.h @@ -0,0 +1,39 @@ +/* +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 "lang.h" + +#include + +namespace Platform { + +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]); +} + +} // 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 000000000..5bd630302 --- /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/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index c62680ea2..d6dcb90ec 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -22,25 +22,39 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "platform/mac/notifications_manager_mac.h" #include "pspecific.h" +#include "platform/mac/mac_utilities.h" + +#include + +NSImage *qt_mac_create_nsimage(const QPixmap &pm); namespace Platform { namespace Notifications { +namespace { + +NeverFreedPointer ManagerInstance; + +} // namespace void start() { + if (cPlatform() != dbipMacOld) { + ManagerInstance.makeIfNull(); + } } Window::Notifications::Manager *manager() { - return nullptr; + return ManagerInstance.data(); } void finish() { + ManagerInstance.clear(); } void defaultNotificationShown(QWidget *widget) { widget->hide(); objc_holdOnTop(widget->winId()); widget->show(); - psShowOverAll(w, false); + psShowOverAll(widget, false); } class Manager::Impl { @@ -56,18 +70,23 @@ private: }; void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - auto notification = [[NSUserNotification alloc] init]; + @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:QNSString(title).s()]; - [notification setSubtitle:QNSString(subtitle).s()]; - [notification setInformativeText:QNSString(msg).s()]; + [notification setTitle:Q2NSString(title)]; + [notification setSubtitle:Q2NSString(subtitle)]; + [notification setInformativeText:Q2NSString(msg)]; if (showUserpic && [notification respondsToSelector:@selector(setContentImage:)]) { auto userpic = peer->genUserpic(st::notifyMacPhotoSize); - auto img = qt_mac_create_nsimage(userpic); + NSImage *img = [qt_mac_create_nsimage(userpic) autorelease]; [notification setContentImage:img]; - [img release]; } if (showReplyButton && [notification respondsToSelector:@selector(setHasReplyButton:)]) { @@ -76,24 +95,32 @@ void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString [notification setSoundName:nil]; - auto center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; [center deliverNotification:notification]; - [notification release]; + } } void Manager::Impl::clearAll() { - auto center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSArray *notificationsList = [center deliveredNotifications]; + for (id notify in notificationsList) { + NSDictionary *notifyUserInfo = [notify userInfo]; + auto notifyLaunchId = [[notifyUserInfo objectForKey:@"launch"] unsignedLongLongValue]; + if (notifyLaunchId == Global::LaunchId()) { + [center removeDeliveredNotification:notify]; + } + } [center removeAllDeliveredNotifications]; } void Manager::Impl::clearFromHistory(History *history) { unsigned long long peerId = history->peer->id; - auto center = [NSUserNotificationCenter defaultUserNotificationCenter]; - auto notificationsList = [center deliveredNotifications]; + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + NSArray *notificationsList = [center deliveredNotifications]; for (id notify in notificationsList) { - auto notifyUserInfo = [notify userInfo]; + NSDictionary *notifyUserInfo = [notify userInfo]; auto notifyPeerId = [[notifyUserInfo objectForKey:@"peer"] unsignedLongLongValue]; auto notifyLaunchId = [[notifyUserInfo objectForKey:@"launch"] unsignedLongLongValue]; if (notifyPeerId == peerId && notifyLaunchId == Global::LaunchId()) { @@ -102,6 +129,9 @@ void Manager::Impl::clearFromHistory(History *history) { } } +Manager::Impl::~Impl() { +} + Manager::Manager() : _impl(std_::make_unique()) { } diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.cpp b/Telegram/SourceFiles/platform/win/windows_toasts.cpp index c27db8f74..5f4c967c0 100644 --- a/Telegram/SourceFiles/platform/win/windows_toasts.cpp +++ b/Telegram/SourceFiles/platform/win/windows_toasts.cpp @@ -50,7 +50,7 @@ namespace { // Delete notify photo file after 1 minute of not using. constexpr int kNotifyDeletePhotoAfterMs = 60000; -NeverFreedPointer ToastsManager; +NeverFreedPointer ManagerInstance; ComPtr _notificationManager; ComPtr _notifier; @@ -361,7 +361,7 @@ QString getImage(const StorageKey &key, PeerData *peer) { if (i != _images.cend()) { if (i->until) { i->until = ms + kNotifyDeletePhotoAfterMs; - if (auto manager = ToastsManager.data()) { + if (auto manager = ManagerInstance.data()) { manager->clearNotifyPhotosInMs(-kNotifyDeletePhotoAfterMs); } } @@ -369,7 +369,7 @@ QString getImage(const StorageKey &key, PeerData *peer) { Image v; if (key.first) { v.until = ms + kNotifyDeletePhotoAfterMs; - if (auto manager = ToastsManager.data()) { + if (auto manager = ManagerInstance.data()) { manager->clearNotifyPhotosInMs(-kNotifyDeletePhotoAfterMs); } } else { @@ -391,16 +391,16 @@ QString getImage(const StorageKey &key, PeerData *peer) { void start() { if (init()) { - ToastsManager.makeIfNull(); + ManagerInstance.makeIfNull(); } } Manager *manager() { - return ToastsManager.data(); + return ManagerInstance.data(); } void finish() { - ToastsManager.reset(); + ManagerInstance.clear(); } uint64 clearImages(uint64 ms) { diff --git a/Telegram/SourceFiles/pspecific_mac_p.mm b/Telegram/SourceFiles/pspecific_mac_p.mm index 16a2917c9..eb358b0cf 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "application.h" #include "playerwidget.h" #include "localstorage.h" +#include "platform/mac/mac_utilities.h" #include "lang.h" @@ -32,6 +33,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include +using Platform::Q2NSString; +using Platform::NSlang; +using Platform::NS2QString; + @interface qVisualize : NSObject { } @@ -104,24 +109,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 { } @@ -147,51 +134,51 @@ QString objcString(NSString *str) { class PsMacWindowData { public: - PsMacWindowData(PsMacWindowPrivate *wnd) : - wnd(wnd), - observerHelper([[ObserverHelper alloc] init:wnd]), - notifyHandler([[NotifyHandler alloc] init:wnd]) { - } + PsMacWindowData(PsMacWindowPrivate *wnd) : + wnd(wnd), + observerHelper([[ObserverHelper alloc] init:wnd]), + notifyHandler([[NotifyHandler alloc] init:wnd]) { + } - void onNotifyClick(NSUserNotification *notification) { + 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); - } + wnd->notifyClicked(peerLong, msgId); + } - void onNotifyReply(NSUserNotification *notification) { + 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]); - } + wnd->notifyReplied(peerLong, msgId, [[[notification response] string] UTF8String]); + } - ~PsMacWindowData() { - [observerHelper release]; - [notifyHandler release]; - } + ~PsMacWindowData() { + [observerHelper release]; + [notifyHandler release]; + } - PsMacWindowPrivate *wnd; - ObserverHelper *observerHelper; - NotifyHandler *notifyHandler; + 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,71 +196,85 @@ public: @end @implementation NotifyHandler { - 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) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification { - NSNumber *instObj = [[notification userInfo] objectForKey:@"launch"]; + 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]; + 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; + 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]; + [NSApp requestUserAttention:NSInformationalRequest]; } void PsMacWindowPrivate::updateDelegate() { - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - [center setDelegate:data->notifyHandler]; + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center setDelegate:data->notifyHandler]; } 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]; @@ -287,15 +288,13 @@ void objc_bringToBack(WId winId) { } void objc_activateWnd(WId winId) { - NSWindow *wnd = [reinterpret_cast(winId) window]; - [wnd orderFront:wnd]; + NSWindow *wnd = [reinterpret_cast(winId) window]; + [wnd orderFront:wnd]; } -NSImage *qt_mac_create_nsimage(const QPixmap &pm); - 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) { @@ -333,15 +332,23 @@ bool PsMacWindowPrivate::filterNativeEvent(void *event) { } 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() { @@ -350,52 +357,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); @@ -468,7 +475,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]; @@ -553,7 +560,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]; @@ -578,22 +585,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]; @@ -601,12 +610,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) @@ -618,13 +633,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 @@ -641,260 +656,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() { @@ -925,6 +947,8 @@ void objc_registerCustomScheme() { } BOOL _execUpdater(BOOL update = YES, const QString &crashreport = QString()) { + @autoreleasepool { + NSString *path = @"", *args = @""; @try { path = [[NSBundle mainBundle] bundlePath]; @@ -934,7 +958,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"]; @@ -944,26 +968,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; } @@ -976,8 +1002,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 } @@ -990,7 +1020,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) { @@ -1005,11 +1037,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() { @@ -1043,20 +1081,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) { @@ -1100,7 +1138,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) { @@ -1141,7 +1179,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/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 5048b07d8..170ebd2b0 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -49,6 +49,7 @@ public: void clearFromHistory(History *history) { doClearFromHistory(history); } + virtual ~Manager() = default; protected: virtual void doUpdateAll() = 0; diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index ecd458b4f..3c0c75ba1 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -35,20 +35,20 @@ namespace { // 3 desktop notifies at the same time. constexpr int kNotifyWindowsCount = 3; -NeverFreedPointer FallbackManager; +NeverFreedPointer ManagerInstance; } // namespace void start() { - FallbackManager.makeIfNull(); + ManagerInstance.makeIfNull(); } Manager *manager() { - return FallbackManager.data(); + return ManagerInstance.data(); } void finish() { - FallbackManager.reset(); + ManagerInstance.clear(); } Manager::Manager() { @@ -340,7 +340,7 @@ void Widget::itemRemoved(HistoryItem *deleted) { void Widget::unlinkHistoryAndNotify() { unlinkHistory(); - if (auto manager = FallbackManager.data()) { + if (auto manager = ManagerInstance.data()) { manager->showNextFromQueue(); } } @@ -355,14 +355,14 @@ void Widget::unlinkHistory(History *history) { void Widget::enterEvent(QEvent *e) { if (!_history) return; - if (auto manager = FallbackManager.data()) { + if (auto manager = ManagerInstance.data()) { manager->stopAllHiding(); } } void Widget::leaveEvent(QEvent *e) { if (!_history) return; - if (auto manager = FallbackManager.data()) { + if (auto manager = ManagerInstance.data()) { manager->startAllHiding(); } } @@ -446,7 +446,7 @@ void Widget::step_appearance(float64 ms, bool timer) { } Widget::~Widget() { - if (auto manager = FallbackManager.data()) { + if (auto manager = ManagerInstance.data()) { manager->removeFromShown(this); } } diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 6531e52a0..a897d8894 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -326,6 +326,8 @@ '<(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', @@ -524,6 +526,8 @@ '<(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', From 7f950d2de2ea62b156201b9106652a626d701691 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 19:32:46 +0300 Subject: [PATCH 10/32] Unified code for notification activation events in Windows version. --- .../platform/mac/notifications_manager_mac.h | 3 +- .../platform/win/main_window_win.cpp | 5 +- .../win/notifications_manager_win.cpp | 594 ++++++++++++++++- .../platform/win/notifications_manager_win.h | 32 +- .../platform/win/windows_toasts.cpp | 618 ------------------ .../SourceFiles/platform/win/windows_toasts.h | 61 -- Telegram/SourceFiles/pspecific_win.cpp | 2 +- .../window/notifications_manager.cpp | 25 + .../window/notifications_manager.h | 6 + .../window/notifications_manager_default.cpp | 15 +- Telegram/gyp/Telegram.gyp | 4 - 11 files changed, 660 insertions(+), 705 deletions(-) delete mode 100644 Telegram/SourceFiles/platform/win/windows_toasts.cpp delete mode 100644 Telegram/SourceFiles/platform/win/windows_toasts.h diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h index 3e4c67d94..2ea20da9e 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h @@ -36,11 +36,12 @@ public: Manager(); ~Manager(); -private: +protected: void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; void doClearAllFast() override; void doClearFromHistory(History *history) override; +private: class Impl; std_::unique_ptr _impl; diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index 2003b23a9..407c49881 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -21,7 +21,7 @@ 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/win/notifications_manager_win.h" #include "platform/win/windows_dlls.h" #include "window/notifications_manager.h" #include "mainwindow.h" @@ -814,7 +814,6 @@ void MainWindow::psInitFrameless() { } // RegisterApplicationRestart(NULL, 0); - Toasts::start(); psInitSysMenu(); } @@ -862,7 +861,7 @@ void MainWindow::psUpdatedPosition() { } bool MainWindow::psHasNativeNotifications() { - return (Toasts::manager() != nullptr); + return Notifications::supported(); } Q_DECLARE_METATYPE(QMargins); diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 7f1066ac3..2cf32473b 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -21,24 +21,606 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "platform/win/notifications_manager_win.h" -#include "platform/win/windows_toasts.h" +#include "platform/win/windows_app_user_model_id.h" +#include "platform/win/windows_dlls.h" +#include "mainwindow.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +HICON qt_pixmapToWinHICON(const QPixmap &); + +using namespace Microsoft::WRL; +using namespace ABI::Windows::UI::Notifications; +using namespace ABI::Windows::Data::Xml::Dom; +using namespace Windows::Foundation; namespace Platform { namespace Notifications { +namespace { -void start() { - Toasts::start(); +// Delete notify photo file after 1 minute of not using. +constexpr int kNotifyDeletePhotoAfterMs = 60000; + +NeverFreedPointer ManagerInstance; + +ComPtr _notificationManager; +ComPtr _notifier; +ComPtr _notificationFactory; + +struct NotificationPtr { + NotificationPtr() { + } + NotificationPtr(const ComPtr &ptr) : p(ptr) { + } + ComPtr p; +}; +using Notifications = QMap>; +Notifications _notifications; +struct Image { + uint64 until; + QString path; +}; +using Images = QMap; +Images _images; +bool _imageSavedFlag = false; + +class StringReferenceWrapper { +public: + StringReferenceWrapper(_In_reads_(length) PCWSTR stringRef, _In_ UINT32 length) throw() { + HRESULT hr = Dlls::WindowsCreateStringReference(stringRef, length, &_header, &_hstring); + if (!SUCCEEDED(hr)) { + RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); + } + } + + ~StringReferenceWrapper() { + Dlls::WindowsDeleteString(_hstring); + } + + template + StringReferenceWrapper(_In_reads_(N) wchar_t const (&stringRef)[N]) throw() { + UINT32 length = N - 1; + HRESULT hr = Dlls::WindowsCreateStringReference(stringRef, length, &_header, &_hstring); + if (!SUCCEEDED(hr)) { + RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); + } + } + + template + StringReferenceWrapper(_In_reads_(_) wchar_t(&stringRef)[_]) throw() { + UINT32 length; + HRESULT hr = SizeTToUInt32(wcslen(stringRef), &length); + if (!SUCCEEDED(hr)) { + RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); + } + + Dlls::WindowsCreateStringReference(stringRef, length, &_header, &_hstring); + } + + HSTRING Get() const throw() { + return _hstring; + } + +private: + HSTRING _hstring; + HSTRING_HEADER _header; + +}; + +template +_Check_return_ __inline HRESULT _1_GetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ T** factory) { + return Dlls::RoGetActivationFactory(activatableClassId, IID_INS_ARGS(factory)); } -Window::Notifications::Manager *manager() { +template +inline HRESULT wrap_GetActivationFactory(_In_ HSTRING activatableClassId, _Inout_ Details::ComPtrRef factory) throw() { + return _1_GetActivationFactory(activatableClassId, factory.ReleaseAndGetAddressOf()); +} + +bool init() { + if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8) { + return false; + } + if ((Dlls::SetCurrentProcessExplicitAppUserModelID == nullptr) + || (Dlls::PropVariantToString == nullptr) + || (Dlls::RoGetActivationFactory == nullptr) + || (Dlls::WindowsCreateStringReference == nullptr) + || (Dlls::WindowsDeleteString == nullptr)) { + return false; + } + + if (!AppUserModelId::validateShortcut()) { + return false; + } + + auto appUserModelId = AppUserModelId::getId(); + if (!SUCCEEDED(Dlls::SetCurrentProcessExplicitAppUserModelID(appUserModelId))) { + return false; + } + if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &_notificationManager))) { + return false; + } + if (!SUCCEEDED(_notificationManager->CreateToastNotifierWithId(StringReferenceWrapper(appUserModelId, wcslen(appUserModelId)).Get(), &_notifier))) { + return false; + } + if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &_notificationFactory))) { + return false; + } + QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); + return true; +} + +HRESULT SetNodeValueString(_In_ HSTRING inputString, _In_ IXmlNode *node, _In_ IXmlDocument *xml) { + ComPtr inputText; + + HRESULT hr = xml->CreateTextNode(inputString, &inputText); + if (!SUCCEEDED(hr)) return hr; + ComPtr inputTextNode; + + hr = inputText.As(&inputTextNode); + if (!SUCCEEDED(hr)) return hr; + + ComPtr pAppendedChild; + return node->AppendChild(inputTextNode.Get(), &pAppendedChild); +} + +HRESULT SetAudioSilent(_In_ IXmlDocument *toastXml) { + ComPtr nodeList; + HRESULT hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"audio").Get(), &nodeList); + if (!SUCCEEDED(hr)) return hr; + + ComPtr audioNode; + hr = nodeList->Item(0, &audioNode); + if (!SUCCEEDED(hr)) return hr; + + if (audioNode) { + ComPtr audioElement; + hr = audioNode.As(&audioElement); + if (!SUCCEEDED(hr)) return hr; + + hr = audioElement->SetAttribute(StringReferenceWrapper(L"silent").Get(), StringReferenceWrapper(L"true").Get()); + if (!SUCCEEDED(hr)) return hr; + } else { + ComPtr audioElement; + hr = toastXml->CreateElement(StringReferenceWrapper(L"audio").Get(), &audioElement); + if (!SUCCEEDED(hr)) return hr; + + hr = audioElement->SetAttribute(StringReferenceWrapper(L"silent").Get(), StringReferenceWrapper(L"true").Get()); + if (!SUCCEEDED(hr)) return hr; + + ComPtr audioNode; + hr = audioElement.As(&audioNode); + if (!SUCCEEDED(hr)) return hr; + + ComPtr nodeList; + hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"toast").Get(), &nodeList); + if (!SUCCEEDED(hr)) return hr; + + ComPtr toastNode; + hr = nodeList->Item(0, &toastNode); + if (!SUCCEEDED(hr)) return hr; + + ComPtr appendedNode; + hr = toastNode->AppendChild(audioNode.Get(), &appendedNode); + } + return hr; +} + +HRESULT SetImageSrc(_In_z_ const wchar_t *imagePath, _In_ IXmlDocument *toastXml) { + wchar_t imageSrc[MAX_PATH] = L"file:///"; + HRESULT hr = StringCchCat(imageSrc, ARRAYSIZE(imageSrc), imagePath); + if (!SUCCEEDED(hr)) return hr; + + ComPtr nodeList; + hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"image").Get(), &nodeList); + if (!SUCCEEDED(hr)) return hr; + + ComPtr imageNode; + hr = nodeList->Item(0, &imageNode); + if (!SUCCEEDED(hr)) return hr; + + ComPtr attributes; + hr = imageNode->get_Attributes(&attributes); + if (!SUCCEEDED(hr)) return hr; + + ComPtr srcAttribute; + hr = attributes->GetNamedItem(StringReferenceWrapper(L"src").Get(), &srcAttribute); + if (!SUCCEEDED(hr)) return hr; + + return SetNodeValueString(StringReferenceWrapper(imageSrc).Get(), srcAttribute.Get(), toastXml); +} + +typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastActivatedEventHandler; +typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastDismissedEventHandler; +typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastFailedEventHandler; + +class ToastEventHandler : public Implements { +public: + ToastEventHandler::ToastEventHandler(const PeerId &peer, MsgId msg) : _ref(1), _peerId(peer), _msgId(msg) { + } + ~ToastEventHandler() { + } + + // DesktopToastActivatedEventHandler + IFACEMETHODIMP Invoke(_In_ IToastNotification *sender, _In_ IInspectable* args) { + if (auto manager = ManagerInstance.data()) { + manager->notificationActivated(_peerId, _msgId); + } + return S_OK; + } + + // DesktopToastDismissedEventHandler + IFACEMETHODIMP Invoke(_In_ IToastNotification *sender, _In_ IToastDismissedEventArgs *e) { + ToastDismissalReason tdr; + if (SUCCEEDED(e->get_Reason(&tdr))) { + switch (tdr) { + case ToastDismissalReason_ApplicationHidden: + break; + case ToastDismissalReason_UserCanceled: + case ToastDismissalReason_TimedOut: + default: + if (auto manager = ManagerInstance.data()) { + manager->clearNotification(_peerId, _msgId); + } + break; + } + } + return S_OK; + } + + // DesktopToastFailedEventHandler + IFACEMETHODIMP Invoke(_In_ IToastNotification *sender, _In_ IToastFailedEventArgs *e) { + if (auto manager = ManagerInstance.data()) { + manager->clearNotification(_peerId, _msgId); + } + return S_OK; + } + + // IUnknown + IFACEMETHODIMP_(ULONG) AddRef() { + return InterlockedIncrement(&_ref); + } + + IFACEMETHODIMP_(ULONG) Release() { + ULONG l = InterlockedDecrement(&_ref); + if (l == 0) delete this; + return l; + } + + IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _COM_Outptr_ void **ppv) { + if (IsEqualIID(riid, IID_IUnknown)) + *ppv = static_cast(static_cast(this)); + else if (IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler))) + *ppv = static_cast(this); + else if (IsEqualIID(riid, __uuidof(DesktopToastDismissedEventHandler))) + *ppv = static_cast(this); + else if (IsEqualIID(riid, __uuidof(DesktopToastFailedEventHandler))) + *ppv = static_cast(this); + else *ppv = nullptr; + + if (*ppv) { + reinterpret_cast(*ppv)->AddRef(); + return S_OK; + } + + return E_NOINTERFACE; + } + +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 + kNotifyDeletePhotoAfterMs; + if (auto manager = ManagerInstance.data()) { + manager->clearPhotosInMs(-kNotifyDeletePhotoAfterMs); + } + } + } else { + Image v; + if (key.first) { + v.until = ms + kNotifyDeletePhotoAfterMs; + if (auto manager = ManagerInstance.data()) { + manager->clearPhotosInMs(-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); + _imageSavedFlag = true; + } + return i->path; +} + +} // namespace + +void start() { + if (init()) { + ManagerInstance.makeIfNull(); + } +} + +Manager *manager() { if (Global::WindowsNotifications()) { - return Toasts::manager(); + return ManagerInstance.data(); } return nullptr; } +bool supported() { + return ManagerInstance.data() != nullptr; +} + void finish() { - Toasts::finish(); + ManagerInstance.clear(); +} + +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; +} + +class Manager::Impl { +public: + bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + 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: + QTimer _clearPhotosTimer; + friend class Manager; + +}; + +Manager::Impl::~Impl() { + _notifications.clear(); + if (_notificationManager) _notificationManager.Reset(); + if (_notifier) _notifier.Reset(); + if (_notificationFactory) _notificationFactory.Reset(); + + if (_imageSavedFlag) { + psDeleteDir(cWorkingDir() + qsl("tdata/temp")); + } +} + +void Manager::Impl::clearAll() { + if (!_notifier) return; + + auto temp = createAndSwap(_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 = createAndSwap(i.value()); + _notifications.erase(i); + + for (auto j = temp.cbegin(), e = temp.cend(); j != e; ++j) { + _notifier->Hide(j->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, bool showUserpic, const QString &msg, bool showReplyButton) { + if (!_notificationManager || !_notifier || !_notificationFactory) return false; + + ComPtr toastXml; + bool withSubtitle = !subtitle.isEmpty(); + + HRESULT hr = _notificationManager->GetTemplateContent(withSubtitle ? ToastTemplateType_ToastImageAndText04 : ToastTemplateType_ToastImageAndText02, &toastXml); + if (!SUCCEEDED(hr)) return false; + + hr = SetAudioSilent(toastXml.Get()); + if (!SUCCEEDED(hr)) return false; + + StorageKey key; + QString imagePath; + if (showUserpic) { + key = peer->userpicUniqueKey(); + } else { + key = StorageKey(0, 0); + } + QString image = getImage(key, peer); + std::wstring wimage = QDir::toNativeSeparators(image).toStdWString(); + + hr = SetImageSrc(wimage.c_str(), toastXml.Get()); + if (!SUCCEEDED(hr)) return false; + + ComPtr nodeList; + hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"text").Get(), &nodeList); + if (!SUCCEEDED(hr)) return false; + + UINT32 nodeListLength; + hr = nodeList->get_Length(&nodeListLength); + if (!SUCCEEDED(hr)) return false; + + if (nodeListLength < (withSubtitle ? 3U : 2U)) return false; + + { + ComPtr textNode; + hr = nodeList->Item(0, &textNode); + if (!SUCCEEDED(hr)) return false; + + std::wstring wtitle = title.toStdWString(); + hr = SetNodeValueString(StringReferenceWrapper(wtitle.data(), wtitle.size()).Get(), textNode.Get(), toastXml.Get()); + if (!SUCCEEDED(hr)) return false; + } + if (withSubtitle) { + ComPtr textNode; + hr = nodeList->Item(1, &textNode); + if (!SUCCEEDED(hr)) return false; + + std::wstring wsubtitle = subtitle.toStdWString(); + hr = SetNodeValueString(StringReferenceWrapper(wsubtitle.data(), wsubtitle.size()).Get(), textNode.Get(), toastXml.Get()); + if (!SUCCEEDED(hr)) return false; + } + { + ComPtr textNode; + hr = nodeList->Item(withSubtitle ? 2 : 1, &textNode); + if (!SUCCEEDED(hr)) return false; + + std::wstring wmsg = msg.toStdWString(); + hr = SetNodeValueString(StringReferenceWrapper(wmsg.data(), wmsg.size()).Get(), textNode.Get(), toastXml.Get()); + if (!SUCCEEDED(hr)) return false; + } + + ComPtr toast; + hr = _notificationFactory->CreateToastNotification(toastXml.Get(), &toast); + if (!SUCCEEDED(hr)) return false; + + EventRegistrationToken activatedToken, dismissedToken, failedToken; + ComPtr eventHandler(new ToastEventHandler(peer->id, msgId)); + + hr = toast->add_Activated(eventHandler.Get(), &activatedToken); + if (!SUCCEEDED(hr)) return false; + + hr = toast->add_Dismissed(eventHandler.Get(), &dismissedToken); + if (!SUCCEEDED(hr)) return false; + + hr = toast->add_Failed(eventHandler.Get(), &failedToken); + if (!SUCCEEDED(hr)) return false; + + auto i = _notifications.find(peer->id); + if (i != _notifications.cend()) { + auto j = i->find(msgId); + if (j != i->cend()) { + ComPtr notify = j->p; + i->erase(j); + _notifier->Hide(notify.Get()); + i = _notifications.find(peer->id); + } + } + if (i == _notifications.cend()) { + i = _notifications.insert(peer->id, QMap()); + } + hr = _notifier->Show(toast.Get()); + if (!SUCCEEDED(hr)) { + i = _notifications.find(peer->id); + if (i != _notifications.cend() && i->isEmpty()) _notifications.erase(i); + return false; + } + _notifications[peer->id].insert(msgId, toast); + + return true; +} + +Manager::Manager() : _impl(std_::make_unique()) { + connect(&_impl->_clearPhotosTimer, SIGNAL(timeout()), this, SLOT(onClearPhotos())); +} + +void Manager::clearPhotosInMs(int ms) { + if (ms < 0) { + ms = -ms; + if (_impl->_clearPhotosTimer.isActive() && _impl->_clearPhotosTimer.remainingTime() <= ms) { + return; + } + } + _impl->_clearPhotosTimer.start(ms); +} + +void Manager::clearNotification(PeerId peerId, MsgId msgId) { + _impl->clearNotification(peerId, msgId); +} + +void Manager::onClearPhotos() { + auto ms = getms(true); + auto minuntil = clearImages(ms); + if (minuntil) { + clearPhotosInMs(int32(minuntil - ms)); + } +} + +Manager::~Manager() = default; + +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +} + +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 diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.h b/Telegram/SourceFiles/platform/win/notifications_manager_win.h index 4478c9bad..f1e24d057 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.h +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h @@ -25,12 +25,42 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Platform { namespace Notifications { +class Manager; + void start(); -Window::Notifications::Manager *manager(); +Manager *manager(); +bool supported(); void finish(); inline void defaultNotificationShown(QWidget *widget) { } +class Manager : public QObject, public Window::Notifications::NativeManager { + Q_OBJECT + +public: + Manager(); + + void clearPhotosInMs(int ms); + void clearNotification(PeerId peerId, MsgId msgId); + + ~Manager(); + +private slots: + void onClearPhotos(); + +protected: + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) 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/platform/win/windows_toasts.cpp b/Telegram/SourceFiles/platform/win/windows_toasts.cpp deleted file mode 100644 index 5f4c967c0..000000000 --- a/Telegram/SourceFiles/platform/win/windows_toasts.cpp +++ /dev/null @@ -1,618 +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 "platform/win/windows_toasts.h" - -#include "platform/win/windows_app_user_model_id.h" -#include "platform/win/windows_dlls.h" -#include "mainwindow.h" - -#include -#include - -#include -#include -#include -#include - -#include -#include - -HICON qt_pixmapToWinHICON(const QPixmap &); - -using namespace Microsoft::WRL; -using namespace ABI::Windows::UI::Notifications; -using namespace ABI::Windows::Data::Xml::Dom; -using namespace Windows::Foundation; - -namespace Platform { -namespace Toasts { -namespace { - -// Delete notify photo file after 1 minute of not using. -constexpr int kNotifyDeletePhotoAfterMs = 60000; - -NeverFreedPointer ManagerInstance; - -ComPtr _notificationManager; -ComPtr _notifier; -ComPtr _notificationFactory; - -struct NotificationPtr { - NotificationPtr() { - } - NotificationPtr(const ComPtr &ptr) : p(ptr) { - } - ComPtr p; -}; -using Notifications = QMap>; -Notifications _notifications; -struct Image { - uint64 until; - QString path; -}; -using Images = QMap; -Images _images; -bool _imageSavedFlag = false; - -class StringReferenceWrapper { -public: - StringReferenceWrapper(_In_reads_(length) PCWSTR stringRef, _In_ UINT32 length) throw() { - HRESULT hr = Dlls::WindowsCreateStringReference(stringRef, length, &_header, &_hstring); - if (!SUCCEEDED(hr)) { - RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); - } - } - - ~StringReferenceWrapper() { - Dlls::WindowsDeleteString(_hstring); - } - - template - StringReferenceWrapper(_In_reads_(N) wchar_t const (&stringRef)[N]) throw() { - UINT32 length = N - 1; - HRESULT hr = Dlls::WindowsCreateStringReference(stringRef, length, &_header, &_hstring); - if (!SUCCEEDED(hr)) { - RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); - } - } - - template - StringReferenceWrapper(_In_reads_(_) wchar_t(&stringRef)[_]) throw() { - UINT32 length; - HRESULT hr = SizeTToUInt32(wcslen(stringRef), &length); - if (!SUCCEEDED(hr)) { - RaiseException(static_cast(STATUS_INVALID_PARAMETER), EXCEPTION_NONCONTINUABLE, 0, nullptr); - } - - Dlls::WindowsCreateStringReference(stringRef, length, &_header, &_hstring); - } - - HSTRING Get() const throw() { - return _hstring; - } - -private: - HSTRING _hstring; - HSTRING_HEADER _header; - -}; - -template -_Check_return_ __inline HRESULT _1_GetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ T** factory) { - return Dlls::RoGetActivationFactory(activatableClassId, IID_INS_ARGS(factory)); -} - -template -inline HRESULT wrap_GetActivationFactory(_In_ HSTRING activatableClassId, _Inout_ Details::ComPtrRef factory) throw() { - return _1_GetActivationFactory(activatableClassId, factory.ReleaseAndGetAddressOf()); -} - -bool init() { - if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8) { - return false; - } - if ((Dlls::SetCurrentProcessExplicitAppUserModelID == nullptr) - || (Dlls::PropVariantToString == nullptr) - || (Dlls::RoGetActivationFactory == nullptr) - || (Dlls::WindowsCreateStringReference == nullptr) - || (Dlls::WindowsDeleteString == nullptr)) { - return false; - } - - if (!AppUserModelId::validateShortcut()) { - return false; - } - - auto appUserModelId = AppUserModelId::getId(); - if (!SUCCEEDED(Dlls::SetCurrentProcessExplicitAppUserModelID(appUserModelId))) { - return false; - } - if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotificationManager).Get(), &_notificationManager))) { - return false; - } - if (!SUCCEEDED(_notificationManager->CreateToastNotifierWithId(StringReferenceWrapper(appUserModelId, wcslen(appUserModelId)).Get(), &_notifier))) { - return false; - } - if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &_notificationFactory))) { - return false; - } - QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); - return true; -} - -HRESULT SetNodeValueString(_In_ HSTRING inputString, _In_ IXmlNode *node, _In_ IXmlDocument *xml) { - ComPtr inputText; - - HRESULT hr = xml->CreateTextNode(inputString, &inputText); - if (!SUCCEEDED(hr)) return hr; - ComPtr inputTextNode; - - hr = inputText.As(&inputTextNode); - if (!SUCCEEDED(hr)) return hr; - - ComPtr pAppendedChild; - return node->AppendChild(inputTextNode.Get(), &pAppendedChild); -} - -HRESULT SetAudioSilent(_In_ IXmlDocument *toastXml) { - ComPtr nodeList; - HRESULT hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"audio").Get(), &nodeList); - if (!SUCCEEDED(hr)) return hr; - - ComPtr audioNode; - hr = nodeList->Item(0, &audioNode); - if (!SUCCEEDED(hr)) return hr; - - if (audioNode) { - ComPtr audioElement; - hr = audioNode.As(&audioElement); - if (!SUCCEEDED(hr)) return hr; - - hr = audioElement->SetAttribute(StringReferenceWrapper(L"silent").Get(), StringReferenceWrapper(L"true").Get()); - if (!SUCCEEDED(hr)) return hr; - } else { - ComPtr audioElement; - hr = toastXml->CreateElement(StringReferenceWrapper(L"audio").Get(), &audioElement); - if (!SUCCEEDED(hr)) return hr; - - hr = audioElement->SetAttribute(StringReferenceWrapper(L"silent").Get(), StringReferenceWrapper(L"true").Get()); - if (!SUCCEEDED(hr)) return hr; - - ComPtr audioNode; - hr = audioElement.As(&audioNode); - if (!SUCCEEDED(hr)) return hr; - - ComPtr nodeList; - hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"toast").Get(), &nodeList); - if (!SUCCEEDED(hr)) return hr; - - ComPtr toastNode; - hr = nodeList->Item(0, &toastNode); - if (!SUCCEEDED(hr)) return hr; - - ComPtr appendedNode; - hr = toastNode->AppendChild(audioNode.Get(), &appendedNode); - } - return hr; -} - -HRESULT SetImageSrc(_In_z_ const wchar_t *imagePath, _In_ IXmlDocument *toastXml) { - wchar_t imageSrc[MAX_PATH] = L"file:///"; - HRESULT hr = StringCchCat(imageSrc, ARRAYSIZE(imageSrc), imagePath); - if (!SUCCEEDED(hr)) return hr; - - ComPtr nodeList; - hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"image").Get(), &nodeList); - if (!SUCCEEDED(hr)) return hr; - - ComPtr imageNode; - hr = nodeList->Item(0, &imageNode); - if (!SUCCEEDED(hr)) return hr; - - ComPtr attributes; - hr = imageNode->get_Attributes(&attributes); - if (!SUCCEEDED(hr)) return hr; - - ComPtr srcAttribute; - hr = attributes->GetNamedItem(StringReferenceWrapper(L"src").Get(), &srcAttribute); - if (!SUCCEEDED(hr)) return hr; - - return SetNodeValueString(StringReferenceWrapper(imageSrc).Get(), srcAttribute.Get(), toastXml); -} - -typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastActivatedEventHandler; -typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastDismissedEventHandler; -typedef ABI::Windows::Foundation::ITypedEventHandler DesktopToastFailedEventHandler; - -class ToastEventHandler : public Implements { -public: - - ToastEventHandler::ToastEventHandler(const PeerId &peer, MsgId msg) : _ref(1), _peerId(peer), _msgId(msg) { - } - ~ToastEventHandler() { - } - - // 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()); - } - return S_OK; - } - - // DesktopToastDismissedEventHandler - IFACEMETHODIMP Invoke(_In_ IToastNotification *sender, _In_ IToastDismissedEventArgs *e) { - ToastDismissalReason tdr; - if (SUCCEEDED(e->get_Reason(&tdr))) { - switch (tdr) { - case ToastDismissalReason_ApplicationHidden: - break; - 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); - } - } - break; - } - } - return S_OK; - } - - // 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); - } - } - return S_OK; - } - - // IUnknown - IFACEMETHODIMP_(ULONG) AddRef() { - return InterlockedIncrement(&_ref); - } - - IFACEMETHODIMP_(ULONG) Release() { - ULONG l = InterlockedDecrement(&_ref); - if (l == 0) delete this; - return l; - } - - IFACEMETHODIMP QueryInterface(_In_ REFIID riid, _COM_Outptr_ void **ppv) { - if (IsEqualIID(riid, IID_IUnknown)) - *ppv = static_cast(static_cast(this)); - else if (IsEqualIID(riid, __uuidof(DesktopToastActivatedEventHandler))) - *ppv = static_cast(this); - else if (IsEqualIID(riid, __uuidof(DesktopToastDismissedEventHandler))) - *ppv = static_cast(this); - else if (IsEqualIID(riid, __uuidof(DesktopToastFailedEventHandler))) - *ppv = static_cast(this); - else *ppv = nullptr; - - if (*ppv) { - reinterpret_cast(*ppv)->AddRef(); - return S_OK; - } - - return E_NOINTERFACE; - } - -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 + kNotifyDeletePhotoAfterMs; - if (auto manager = ManagerInstance.data()) { - manager->clearNotifyPhotosInMs(-kNotifyDeletePhotoAfterMs); - } - } - } else { - Image v; - if (key.first) { - v.until = ms + kNotifyDeletePhotoAfterMs; - if (auto manager = ManagerInstance.data()) { - manager->clearNotifyPhotosInMs(-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); - _imageSavedFlag = true; - } - return i->path; -} - -} // namespace - -void start() { - if (init()) { - ManagerInstance.makeIfNull(); - } -} - -Manager *manager() { - return ManagerInstance.data(); -} - -void finish() { - ManagerInstance.clear(); -} - -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; -} - -class Manager::Impl { -public: - bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); - void clearAll(); - void clearFromHistory(History *history); - - ~Impl(); - -private: - QTimer _clearNotifyPhotosTimer; - friend class Manager; - -}; - -Manager::Impl::~Impl() { - _notifications.clear(); - if (_notificationManager) _notificationManager.Reset(); - if (_notifier) _notifier.Reset(); - if (_notificationFactory) _notificationFactory.Reset(); - - if (_imageSavedFlag) { - psDeleteDir(cWorkingDir() + qsl("tdata/temp")); - } -} - -void Manager::Impl::clearAll() { - if (!_notifier) return; - - auto temp = createAndSwap(_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 = createAndSwap(i.value()); - _notifications.erase(i); - - for (auto j = temp.cbegin(), e = temp.cend(); j != e; ++j) { - _notifier->Hide(j->p.Get()); - } - } -} - -bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - if (!_notificationManager || !_notifier || !_notificationFactory) return false; - - ComPtr toastXml; - bool withSubtitle = !subtitle.isEmpty(); - - HRESULT hr = _notificationManager->GetTemplateContent(withSubtitle ? ToastTemplateType_ToastImageAndText04 : ToastTemplateType_ToastImageAndText02, &toastXml); - if (!SUCCEEDED(hr)) return false; - - hr = SetAudioSilent(toastXml.Get()); - if (!SUCCEEDED(hr)) return false; - - StorageKey key; - QString imagePath; - if (showUserpic) { - key = peer->userpicUniqueKey(); - } else { - key = StorageKey(0, 0); - } - QString image = getImage(key, peer); - std::wstring wimage = QDir::toNativeSeparators(image).toStdWString(); - - hr = SetImageSrc(wimage.c_str(), toastXml.Get()); - if (!SUCCEEDED(hr)) return false; - - ComPtr nodeList; - hr = toastXml->GetElementsByTagName(StringReferenceWrapper(L"text").Get(), &nodeList); - if (!SUCCEEDED(hr)) return false; - - UINT32 nodeListLength; - hr = nodeList->get_Length(&nodeListLength); - if (!SUCCEEDED(hr)) return false; - - if (nodeListLength < (withSubtitle ? 3U : 2U)) return false; - - { - ComPtr textNode; - hr = nodeList->Item(0, &textNode); - if (!SUCCEEDED(hr)) return false; - - std::wstring wtitle = title.toStdWString(); - hr = SetNodeValueString(StringReferenceWrapper(wtitle.data(), wtitle.size()).Get(), textNode.Get(), toastXml.Get()); - if (!SUCCEEDED(hr)) return false; - } - if (withSubtitle) { - ComPtr textNode; - hr = nodeList->Item(1, &textNode); - if (!SUCCEEDED(hr)) return false; - - std::wstring wsubtitle = subtitle.toStdWString(); - hr = SetNodeValueString(StringReferenceWrapper(wsubtitle.data(), wsubtitle.size()).Get(), textNode.Get(), toastXml.Get()); - if (!SUCCEEDED(hr)) return false; - } - { - ComPtr textNode; - hr = nodeList->Item(withSubtitle ? 2 : 1, &textNode); - if (!SUCCEEDED(hr)) return false; - - std::wstring wmsg = msg.toStdWString(); - hr = SetNodeValueString(StringReferenceWrapper(wmsg.data(), wmsg.size()).Get(), textNode.Get(), toastXml.Get()); - if (!SUCCEEDED(hr)) return false; - } - - ComPtr toast; - hr = _notificationFactory->CreateToastNotification(toastXml.Get(), &toast); - if (!SUCCEEDED(hr)) return false; - - EventRegistrationToken activatedToken, dismissedToken, failedToken; - ComPtr eventHandler(new ToastEventHandler(peer->id, msgId)); - - hr = toast->add_Activated(eventHandler.Get(), &activatedToken); - if (!SUCCEEDED(hr)) return false; - - hr = toast->add_Dismissed(eventHandler.Get(), &dismissedToken); - if (!SUCCEEDED(hr)) return false; - - hr = toast->add_Failed(eventHandler.Get(), &failedToken); - if (!SUCCEEDED(hr)) return false; - - auto i = _notifications.find(peer->id); - if (i != _notifications.cend()) { - auto j = i->find(msgId); - if (j != i->cend()) { - ComPtr notify = j->p; - i->erase(j); - _notifier->Hide(notify.Get()); - i = _notifications.find(peer->id); - } - } - if (i == _notifications.cend()) { - i = _notifications.insert(peer->id, QMap()); - } - hr = _notifier->Show(toast.Get()); - if (!SUCCEEDED(hr)) { - i = _notifications.find(peer->id); - if (i != _notifications.cend() && i->isEmpty()) _notifications.erase(i); - return false; - } - _notifications[peer->id].insert(msgId, toast); - - return true; -} - -Manager::Manager() : _impl(std_::make_unique()) { - connect(&_impl->_clearNotifyPhotosTimer, SIGNAL(timeout()), this, SLOT(onClearNotifyPhotos())); -} - -void Manager::clearNotifyPhotosInMs(int ms) { - if (ms < 0) { - ms = -ms; - if (_impl->_clearNotifyPhotosTimer.isActive() && _impl->_clearNotifyPhotosTimer.remainingTime() <= ms) { - return; - } - } - _impl->_clearNotifyPhotosTimer.start(ms); -} - -void Manager::onClearNotifyPhotos() { - auto ms = getms(true); - auto minuntil = Toasts::clearImages(ms); - if (minuntil) { - clearNotifyPhotosInMs(int32(minuntil - ms)); - } -} - -Manager::~Manager() = default; - -void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); -} - -void Manager::doClearAllFast() { - _impl->clearAll(); -} - -void Manager::doClearFromHistory(History *history) { - _impl->clearFromHistory(history); -} - -} // namespace Toasts -} // namespace Platform diff --git a/Telegram/SourceFiles/platform/win/windows_toasts.h b/Telegram/SourceFiles/platform/win/windows_toasts.h deleted file mode 100644 index 517f4aedc..000000000 --- a/Telegram/SourceFiles/platform/win/windows_toasts.h +++ /dev/null @@ -1,61 +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 -*/ -#pragma once - -#include "window/notifications_manager.h" - -namespace Platform { -namespace Toasts { - -class Manager; - -void start(); -Manager *manager(); -void finish(); - -// Returns the next ms when clearImages() should be called. -uint64 clearImages(uint64 ms); - -class Manager : public QObject, public Window::Notifications::NativeManager { - Q_OBJECT - -public: - Manager(); - - void clearNotifyPhotosInMs(int ms); - - ~Manager(); - -private slots: - void onClearNotifyPhotos(); - -private: - void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; - void doClearAllFast() override; - void doClearFromHistory(History *history) override; - - class Impl; - std_::unique_ptr _impl; - -}; - -} // namespace Toasts -} // namespace Platform diff --git a/Telegram/SourceFiles/pspecific_win.cpp b/Telegram/SourceFiles/pspecific_win.cpp index 61fcde541..72ade2e76 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/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index ac05db88e..e3249ab52 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "platform/platform_notifications_manager.h" #include "window/notifications_manager_default.h" #include "lang.h" +#include "mainwindow.h" namespace Window { namespace Notifications { @@ -45,6 +46,30 @@ void finish() { Default::finish(); } +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 NativeManager::doShowNotification(HistoryItem *item, int forwardedCount) { auto hideEverything = (App::passcoded() || Global::ScreenIsLocked()); auto hideName = hideEverything || (Global::NotifyView() > dbinvShowName); diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 170ebd2b0..02a2b15b7 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -49,6 +49,8 @@ public: void clearFromHistory(History *history) { doClearFromHistory(history); } + void notificationActivated(PeerId peerId, MsgId msgId); + virtual ~Manager() = default; protected: @@ -58,6 +60,10 @@ protected: 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) { + } }; diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 3c0c75ba1..5d331b4b7 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -374,20 +374,15 @@ void Widget::startHiding() { void Widget::mousePressEvent(QMouseEvent *e) { if (!_history) return; - auto peerId = _history->peer->id; - auto 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(peerId, msgId); - } e->ignore(); + if (auto manager = ManagerInstance.data()) { + auto peerId = _history->peer->id; + auto msgId = _item ? _item->id : ShowAtUnreadMsgId; + manager->notificationActivated(peerId, msgId); + } } } diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index a897d8894..41df54189 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -342,8 +342,6 @@ '<(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', @@ -555,8 +553,6 @@ '<(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', ], }], ], From 2d1d62a95328927ebfb02a4a7c70b9dbfa54284a Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 2 Oct 2016 20:06:34 +0300 Subject: [PATCH 11/32] Code for replying from notifications, macOS uses notificationActivated(). --- .../platform/linux/main_window_linux.cpp | 4 - .../platform/linux/main_window_linux.h | 2 - .../platform/mac/main_window_mac.h | 4 - .../platform/mac/main_window_mac.mm | 43 +------ .../platform/mac/notifications_manager_mac.h | 7 +- .../platform/mac/notifications_manager_mac.mm | 110 +++++++++++++++--- .../platform/win/main_window_win.cpp | 4 - .../platform/win/main_window_win.h | 1 - Telegram/SourceFiles/pspecific_mac_p.h | 7 -- Telegram/SourceFiles/pspecific_mac_p.mm | 71 +---------- .../window/notifications_manager.cpp | 17 +++ .../window/notifications_manager.h | 2 + 12 files changed, 125 insertions(+), 147 deletions(-) diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index ecd15172c..e35e753e8 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -268,7 +268,6 @@ void MainWindow::psSetupTrayIcon() { psUpdateCounter(); trayIcon->show(); - psUpdateDelegate(); } } @@ -430,9 +429,6 @@ void MainWindow::LibsLoaded() { #endif // TDESKTOP_DISABLE_UNITY_INTEGRATION } -void MainWindow::psUpdateDelegate() { -} - void MainWindow::psInitSize() { setMinimumWidth(st::wndMinWidth); setMinimumHeight(st::wndMinHeight); diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index 739063177..a7cee027e 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -69,8 +69,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.h b/Telegram/SourceFiles/platform/mac/main_window_mac.h index 434cb93ed..ddbd582a7 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.h +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.h @@ -27,11 +27,8 @@ 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); }; @@ -83,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 08fa8495b..ddf50c906 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "historywidget.h" #include "localstorage.h" #include "window/notifications_manager_default.h" +#include "platform/mac/notifications_manager_mac.h" #include "lang.h" @@ -48,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")) @@ -151,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); } @@ -220,10 +191,6 @@ void MainWindow::psUpdateCounter() { } } -void MainWindow::psUpdateDelegate() { - _private.updateDelegate(); -} - void MainWindow::psInitSize() { setMinimumWidth(st::wndMinWidth); setMinimumHeight(st::wndMinHeight); diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h index 2ea20da9e..bb466f1b8 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h @@ -25,8 +25,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Platform { namespace Notifications { +class Manager; + void start(); -Window::Notifications::Manager *manager(); +Manager *manager(); void finish(); void defaultNotificationShown(QWidget *widget); @@ -34,6 +36,9 @@ void defaultNotificationShown(QWidget *widget); class Manager : public Window::Notifications::NativeManager { public: Manager(); + + void updateDelegate(); + ~Manager(); protected: diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index d6dcb90ec..831fce549 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -26,15 +26,72 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #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 { -namespace { - -NeverFreedPointer ManagerInstance; - -} // namespace void start() { if (cPlatform() != dbipMacOld) { @@ -42,7 +99,7 @@ void start() { } } -Window::Notifications::Manager *manager() { +Manager *manager() { return ManagerInstance.data(); } @@ -59,16 +116,22 @@ void defaultNotificationShown(QWidget *widget) { class Manager::Impl { public: + Impl(); void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); 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, bool showUserpic, const QString &msg, bool showReplyButton) { @autoreleasepool { @@ -104,11 +167,12 @@ void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString void Manager::Impl::clearAll() { NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; NSArray *notificationsList = [center deliveredNotifications]; - for (id notify in notificationsList) { - NSDictionary *notifyUserInfo = [notify userInfo]; - auto notifyLaunchId = [[notifyUserInfo objectForKey:@"launch"] unsignedLongLongValue]; - if (notifyLaunchId == Global::LaunchId()) { - [center removeDeliveredNotification:notify]; + 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]; @@ -119,22 +183,34 @@ void Manager::Impl::clearFromHistory(History *history) { NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; NSArray *notificationsList = [center deliveredNotifications]; - for (id notify in notificationsList) { - NSDictionary *notifyUserInfo = [notify userInfo]; - auto notifyPeerId = [[notifyUserInfo objectForKey:@"peer"] unsignedLongLongValue]; - auto notifyLaunchId = [[notifyUserInfo objectForKey:@"launch"] unsignedLongLongValue]; - if (notifyPeerId == peerId && notifyLaunchId == Global::LaunchId()) { - [center removeDeliveredNotification:notify]; + 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, bool showUserpic, const QString &msg, bool showReplyButton) { diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index 407c49881..7294ef2be 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -674,7 +674,6 @@ void MainWindow::psSetupTrayIcon() { psUpdateCounter(); trayIcon->show(); - psUpdateDelegate(); } void MainWindow::psUpdateWorkmode() { @@ -745,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; diff --git a/Telegram/SourceFiles/platform/win/main_window_win.h b/Telegram/SourceFiles/platform/win/main_window_win.h index cd16f71d6..20713abe4 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.h +++ b/Telegram/SourceFiles/platform/win/main_window_win.h @@ -99,7 +99,6 @@ public: ~MainWindow(); public slots: - void psUpdateDelegate(); void psSavePosition(Qt::WindowState state = Qt::WindowActive); void psShowTrayMenu(); diff --git a/Telegram/SourceFiles/pspecific_mac_p.h b/Telegram/SourceFiles/pspecific_mac_p.h index b186e28c1..5a613ceea 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.h +++ b/Telegram/SourceFiles/pspecific_mac_p.h @@ -21,14 +21,11 @@ class PsMacWindowData; class PsMacWindowPrivate { public: - PsMacWindowPrivate(); void setWindowBadge(const QString &str); void startBounce(); - void updateDelegate(); - void enableShadow(WId winId); bool filterNativeEvent(void *event); @@ -37,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 eb358b0cf..7f193d93b 100644 --- a/Telegram/SourceFiles/pspecific_mac_p.mm +++ b/Telegram/SourceFiles/pspecific_mac_p.mm @@ -120,50 +120,20 @@ ApplicationDelegate *_sharedDelegate = nil; @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]), - notifyHandler([[NotifyHandler alloc] init:wnd]) { - } - - 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); - } - - 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]); + observerHelper([[ObserverHelper alloc] init:wnd]) { } ~PsMacWindowData() { [observerHelper release]; - [notifyHandler release]; } PsMacWindowPrivate *wnd; ObserverHelper *observerHelper; - NotifyHandler *notifyHandler; + }; @implementation ObserverHelper { @@ -195,38 +165,6 @@ 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)) { @autoreleasepool { @@ -250,11 +188,6 @@ void PsMacWindowPrivate::startBounce() { [NSApp requestUserAttention:NSInformationalRequest]; } -void PsMacWindowPrivate::updateDelegate() { - NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; - [center setDelegate:data->notifyHandler]; -} - void objc_holdOnTop(WId winId) { NSWindow *wnd = [reinterpret_cast(winId) window]; [wnd setHidesOnDeactivate:NO]; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index e3249ab52..f0c7ed0fb 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/notifications_manager_default.h" #include "lang.h" #include "mainwindow.h" +#include "mainwidget.h" namespace Window { namespace Notifications { @@ -70,6 +71,22 @@ void Manager::notificationActivated(PeerId peerId, MsgId msgId) { 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 hideEverything = (App::passcoded() || Global::ScreenIsLocked()); auto hideName = hideEverything || (Global::NotifyView() > dbinvShowName); diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 02a2b15b7..3ea25c74a 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -49,7 +49,9 @@ public: void clearFromHistory(History *history) { doClearFromHistory(history); } + void notificationActivated(PeerId peerId, MsgId msgId); + void notificationReplied(PeerId peerId, MsgId msgId, const QString &reply); virtual ~Manager() = default; From e1a8c89ff186c7d6ea8221614eee57e1f8f545e6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 11:20:02 +0300 Subject: [PATCH 12/32] Version 0.10.9: don't handle cStartUrl() while passcoded. --- Telegram/SourceFiles/application.cpp | 5 ++--- Telegram/SourceFiles/mainwidget.cpp | 16 ++++++++++++---- Telegram/SourceFiles/mainwidget.h | 1 + Telegram/SourceFiles/mainwindow.cpp | 9 ++++++--- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 9a21f66af..7ca8ba389 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -303,9 +303,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(); } } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 37ac2441b..a84d6bec3 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -3301,10 +3301,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(); @@ -3312,12 +3309,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 84fb26380..a6d3547ee 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -155,6 +155,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 43c59329e..fb2c6e1fa 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -550,6 +550,10 @@ void MainWindow::clearPasscode() { notifyUpdateAll(); title->updateBackButton(); updateGlobalMenu(); + + if (auto main = App::main()) { + main->checkStartUrl(); + } } void MainWindow::setupPasscode(bool anim) { @@ -1040,9 +1044,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(); From 1cc1aab8234e532238e3bb7cef9f3df365380516 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 11:20:02 +0300 Subject: [PATCH 13/32] Version 0.10.9: don't handle cStartUrl() while passcoded. --- Telegram/SourceFiles/application.cpp | 5 ++--- Telegram/SourceFiles/mainwidget.cpp | 16 ++++++++++++---- Telegram/SourceFiles/mainwidget.h | 1 + Telegram/SourceFiles/mainwindow.cpp | 9 ++++++--- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 9a21f66af..7ca8ba389 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -303,9 +303,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(); } } diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 37ac2441b..a84d6bec3 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -3301,10 +3301,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(); @@ -3312,12 +3309,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 84fb26380..a6d3547ee 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -155,6 +155,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 43c59329e..fb2c6e1fa 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -550,6 +550,10 @@ void MainWindow::clearPasscode() { notifyUpdateAll(); title->updateBackButton(); updateGlobalMenu(); + + if (auto main = App::main()) { + main->checkStartUrl(); + } } void MainWindow::setupPasscode(bool anim) { @@ -1040,9 +1044,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(); From 6db52f7fa93902aff5d99564f17f0a2d8942cac2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 11:56:03 +0300 Subject: [PATCH 14/32] LibNotify Linux notifications support added, testing. --- Telegram/SourceFiles/config.h | 4 + .../platform/linux/linux_libnotify.cpp | 118 +++++++++++ .../platform/linux/linux_libnotify.h | 131 ++++++++++++ .../SourceFiles/platform/linux/linux_libs.cpp | 7 + .../SourceFiles/platform/linux/linux_libs.h | 3 + .../platform/linux/main_window_linux.cpp | 11 - .../linux/notifications_manager_linux.cpp | 199 +++++++++++++++++- .../linux/notifications_manager_linux.h | 21 +- .../win/notifications_manager_win.cpp | 103 +-------- .../platform/win/notifications_manager_win.h | 8 +- .../window/notifications_utilities.cpp | 116 ++++++++++ .../window/notifications_utilities.h | 57 +++++ Telegram/gyp/Telegram.gyp | 4 + 13 files changed, 664 insertions(+), 118 deletions(-) create mode 100644 Telegram/SourceFiles/platform/linux/linux_libnotify.cpp create mode 100644 Telegram/SourceFiles/platform/linux/linux_libnotify.h create mode 100644 Telegram/SourceFiles/window/notifications_utilities.cpp create mode 100644 Telegram/SourceFiles/window/notifications_utilities.h diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index a9b18db74..6a0d52540 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -292,6 +292,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 diff --git a/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp new file mode 100644 index 000000000..ddae19ce1 --- /dev/null +++ b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp @@ -0,0 +1,118 @@ +/* +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)) { + 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 000000000..e59431ffe --- /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 484b6c534..92185611e 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 { @@ -175,6 +176,7 @@ 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; @@ -233,6 +235,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 +269,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 6fd9a802f..88f1e659c 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.h +++ b/Telegram/SourceFiles/platform/linux/linux_libs.h @@ -273,6 +273,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; diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index e35e753e8..9559058f5 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -63,22 +63,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 diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index ca680140b..5ef3467cf 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -21,17 +21,210 @@ 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" + namespace Platform { namespace Notifications { +namespace { -void start() { +NeverFreedPointer ManagerInstance; + +bool supported() { + 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_unref != nullptr) +// && (Libs::gdk_pixbuf_new_from_data != nullptr) + && (Libs::gdk_pixbuf_new_from_file != nullptr); } -Window::Notifications::Manager *manager() { - return nullptr; +} // namespace + +void start() { + if (supported()) { + if (Libs::notify_is_initted() || Libs::notify_init("Telegram Desktop")) { + ManagerInstance.makeIfNull(); + } + } +} + +Manager *manager() { + return ManagerInstance.data(); } void finish() { + if (manager()) { + ManagerInstance.reset(); + Libs::notify_uninit(); + } +} + +class Manager::Impl { +public: + void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + void clearAll(); + void clearFromHistory(History *history); + +private: + static void notificationClosed(Libs::NotifyNotification *notification, gpointer data); + void clearNotification(Libs::NotifyNotification *notification); + + using Notifications = QMap>; + Notifications _notifications; + + using NotificationsData = QMap>; + NotificationsData _notificationsData; + + Window::Notifications::CachedUserpics _cachedUserpics; + +}; + +void Manager::Impl::notificationClosed(Libs::NotifyNotification *notification, gpointer data) { + if (auto manager = ManagerInstance.data()) { + manager->_impl->clearNotification(notification); + } +} + +void Manager::Impl::clearNotification(Libs::NotifyNotification *notification) { + auto dataIt = _notificationsData.find(notification); + if (dataIt == _notificationsData.cend()) { + return; + } + + auto peerId = dataIt->first; + auto msgId = dataIt->second; + _notificationsData.erase(dataIt); + + auto i = _notifications.find(peerId); + if (i != _notifications.cend()) { + auto it = i.value().find(msgId); + if (it != i.value().cend()) { + Libs::g_object_unref(Libs::g_object_cast(it.value())); + i.value().erase(it); + if (i.value().isEmpty()) { + _notifications.erase(i); + } + } + } +} + +void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + auto titleUtf8 = title.toUtf8(); + auto bodyUtf8 = (subtitle.isEmpty() ? msg : ("" + subtitle + "\n" + msg)).toUtf8(); + auto notification = Libs::notify_notification_new(titleUtf8.constData(), bodyUtf8.constData(), nullptr); + if (!notification) { + return; + } + + Libs::g_signal_connect_helper(Libs::g_object_cast(notification), "closed", G_CALLBACK(Manager::Impl::notificationClosed), peer); + + StorageKey key; + if (showUserpic) { + key = peer->userpicUniqueKey(); + } else { + key = StorageKey(0, 0); + } + auto userpicPath = _cachedUserpics.get(key, peer); + auto userpicPathNative = QFile::encodeName(userpicPath); + if (auto pixbuf = Libs::gdk_pixbuf_new_from_file(userpicPathNative.constData(), nullptr)) { + Libs::notify_notification_set_image_from_pixbuf(notification, pixbuf); + Libs::g_object_unref(Libs::g_object_cast(pixbuf)); + } + + auto i = _notifications.find(peer->id); + if (i != _notifications.cend()) { + auto j = i->find(msgId); + if (j != i->cend()) { + auto oldNotification = j.value(); + i->erase(j); + _notificationsData.remove(oldNotification); + Libs::notify_notification_close(oldNotification, nullptr); + Libs::g_object_unref(Libs::g_object_cast(oldNotification)); + i = _notifications.find(peer->id); + } + } + if (i == _notifications.cend()) { + i = _notifications.insert(peer->id, QMap()); + } + auto result = Libs::notify_notification_show(notification, nullptr); + if (!result) { + Libs::g_object_unref(Libs::g_object_cast(notification)); + i = _notifications.find(peer->id); + if (i != _notifications.cend() && i->isEmpty()) _notifications.erase(i); + return; + } + _notifications[peer->id].insert(msgId, notification); + _notificationsData.insert(notification, qMakePair(peer->id, msgId)); +} + +void Manager::Impl::clearAll() { + _notificationsData.clear(); + + auto temp = createAndSwap(_notifications); + for_const (auto ¬ifications, temp) { + for_const (auto notification, notifications) { + Libs::notify_notification_close(notification, nullptr); + Libs::g_object_unref(Libs::g_object_cast(notification)); + } + } +} + +void Manager::Impl::clearFromHistory(History *history) { + auto i = _notifications.find(history->peer->id); + if (i != _notifications.cend()) { + auto temp = createAndSwap(i.value()); + _notifications.erase(i); + + for_const (auto notification, temp) { + _notificationsData.remove(notification); + Libs::notify_notification_close(notification, nullptr); + Libs::g_object_unref(Libs::g_object_cast(notification)); + } + } +} + +Manager::Manager() : _impl(std_::make_unique()) { +} + +Manager::~Manager() = default; + +void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { + _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +} + +void Manager::doClearAllFast() { + _impl->clearAll(); +} + +void Manager::doClearFromHistory(History *history) { + _impl->clearFromHistory(history); } } // namespace Notifications diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h index 4478c9bad..e7b7e0683 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -25,12 +25,31 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Platform { namespace Notifications { +class Manager; + void start(); -Window::Notifications::Manager *manager(); +Manager *manager(); void finish(); inline void defaultNotificationShown(QWidget *widget) { } +class Manager : public Window::Notifications::NativeManager { +public: + Manager(); + ~Manager(); + +protected: + void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) 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/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 2cf32473b..417f18604 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -21,6 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.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" @@ -47,9 +48,6 @@ namespace Platform { namespace Notifications { namespace { -// Delete notify photo file after 1 minute of not using. -constexpr int kNotifyDeletePhotoAfterMs = 60000; - NeverFreedPointer ManagerInstance; ComPtr _notificationManager; @@ -65,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: @@ -155,7 +146,6 @@ bool init() { if (!SUCCEEDED(wrap_GetActivationFactory(StringReferenceWrapper(RuntimeClass_Windows_UI_Notifications_ToastNotification).Get(), &_notificationFactory))) { return false; } - QDir().mkpath(cWorkingDir() + qsl("tdata/temp")); return true; } @@ -322,38 +312,6 @@ private: }; -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 + kNotifyDeletePhotoAfterMs; - if (auto manager = ManagerInstance.data()) { - manager->clearPhotosInMs(-kNotifyDeletePhotoAfterMs); - } - } - } else { - Image v; - if (key.first) { - v.until = ms + kNotifyDeletePhotoAfterMs; - if (auto manager = ManagerInstance.data()) { - manager->clearPhotosInMs(-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); - _imageSavedFlag = true; - } - return i->path; -} - } // namespace void start() { @@ -377,28 +335,6 @@ void finish() { ManagerInstance.clear(); } -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; -} - class Manager::Impl { public: bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); @@ -411,8 +347,7 @@ public: ~Impl(); private: - QTimer _clearPhotosTimer; - friend class Manager; + Window::Notifications::CachedUserpics _cachedUserpics; }; @@ -421,10 +356,6 @@ Manager::Impl::~Impl() { if (_notificationManager) _notificationManager.Reset(); if (_notifier) _notifier.Reset(); if (_notificationFactory) _notificationFactory.Reset(); - - if (_imageSavedFlag) { - psDeleteDir(cWorkingDir() + qsl("tdata/temp")); - } } void Manager::Impl::clearAll() { @@ -446,8 +377,8 @@ void Manager::Impl::clearFromHistory(History *history) { auto temp = createAndSwap(i.value()); _notifications.erase(i); - for (auto j = temp.cbegin(), e = temp.cend(); j != e; ++j) { - _notifier->Hide(j->p.Get()); + for_const (auto ¬ification, temp) { + _notifier->Hide(notification.p.Get()); } } } @@ -485,16 +416,15 @@ bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString if (!SUCCEEDED(hr)) return false; StorageKey key; - QString imagePath; if (showUserpic) { key = peer->userpicUniqueKey(); } else { key = StorageKey(0, 0); } - 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; @@ -576,31 +506,12 @@ bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString } Manager::Manager() : _impl(std_::make_unique()) { - connect(&_impl->_clearPhotosTimer, SIGNAL(timeout()), this, SLOT(onClearPhotos())); -} - -void Manager::clearPhotosInMs(int ms) { - if (ms < 0) { - ms = -ms; - if (_impl->_clearPhotosTimer.isActive() && _impl->_clearPhotosTimer.remainingTime() <= ms) { - return; - } - } - _impl->_clearPhotosTimer.start(ms); } void Manager::clearNotification(PeerId peerId, MsgId msgId) { _impl->clearNotification(peerId, msgId); } -void Manager::onClearPhotos() { - auto ms = getms(true); - auto minuntil = clearImages(ms); - if (minuntil) { - clearPhotosInMs(int32(minuntil - ms)); - } -} - Manager::~Manager() = default; void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.h b/Telegram/SourceFiles/platform/win/notifications_manager_win.h index f1e24d057..37597a175 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.h +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h @@ -35,20 +35,14 @@ void finish(); inline void defaultNotificationShown(QWidget *widget) { } -class Manager : public QObject, public Window::Notifications::NativeManager { - Q_OBJECT - +class Manager : public Window::Notifications::NativeManager { public: Manager(); - void clearPhotosInMs(int ms); void clearNotification(PeerId peerId, MsgId msgId); ~Manager(); -private slots: - void onClearPhotos(); - protected: void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; void doClearAllFast() override; diff --git a/Telegram/SourceFiles/window/notifications_utilities.cpp b/Telegram/SourceFiles/window/notifications_utilities.cpp new file mode 100644 index 000000000..db2aae815 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_utilities.cpp @@ -0,0 +1,116 @@ +/* +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" + +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 000000000..384690d30 --- /dev/null +++ b/Telegram/SourceFiles/window/notifications_utilities.h @@ -0,0 +1,57 @@ +/* +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 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/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 41df54189..cb4b63355 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -318,6 +318,8 @@ '<(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', @@ -486,6 +488,8 @@ '<(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', From aa17702c01ba4328885bbf169aa243f0008e68bd Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 13:08:22 +0300 Subject: [PATCH 15/32] 0.10.10: Crashfix: Removed infinite recursion in Ui::FadeAnimation(). --- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/SourceFiles/ui/effects/fade_animation.cpp | 2 +- Telegram/build/version | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 449d1fc2e..2b84c45ad 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,9,0 - PRODUCTVERSION 0,10,9,0 + FILEVERSION 0,10,10,0 + PRODUCTVERSION 0,10,10,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.9.0" + VALUE "FileVersion", "0.10.10.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.9.0" + VALUE "ProductVersion", "0.10.10.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index a3d19de62..3a100ee90 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,9,0 - PRODUCTVERSION 0,10,9,0 + FILEVERSION 0,10,10,0 + PRODUCTVERSION 0,10,10,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.9.0" + VALUE "FileVersion", "0.10.10.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.9.0" + VALUE "ProductVersion", "0.10.10.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 6505e548a..16c522220 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10009; -constexpr str_const AppVersionStr = "0.10.9"; +constexpr int AppVersion = 10010; +constexpr str_const AppVersionStr = "0.10.10"; constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/ui/effects/fade_animation.cpp b/Telegram/SourceFiles/ui/effects/fade_animation.cpp index 5e2663a5d..2c5cee26a 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/build/version b/Telegram/build/version index 209d05a04..41da4ebe3 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10009 +AppVersion 10010 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.9 -AppVersionStr 0.10.9 +AppVersionStrSmall 0.10.10 +AppVersionStr 0.10.10 AlphaChannel 0 BetaVersion 0 From f710fe2dd3a31bd930a8e5bd083bcd49f0c80f8d Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 13:08:22 +0300 Subject: [PATCH 16/32] 0.10.10: Crashfix: Removed infinite recursion in Ui::FadeAnimation(). --- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/SourceFiles/ui/effects/fade_animation.cpp | 2 +- Telegram/build/version | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 449d1fc2e..2b84c45ad 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,9,0 - PRODUCTVERSION 0,10,9,0 + FILEVERSION 0,10,10,0 + PRODUCTVERSION 0,10,10,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.9.0" + VALUE "FileVersion", "0.10.10.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.9.0" + VALUE "ProductVersion", "0.10.10.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index a3d19de62..3a100ee90 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,9,0 - PRODUCTVERSION 0,10,9,0 + FILEVERSION 0,10,10,0 + PRODUCTVERSION 0,10,10,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.9.0" + VALUE "FileVersion", "0.10.10.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.9.0" + VALUE "ProductVersion", "0.10.10.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 6505e548a..16c522220 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10009; -constexpr str_const AppVersionStr = "0.10.9"; +constexpr int AppVersion = 10010; +constexpr str_const AppVersionStr = "0.10.10"; constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/ui/effects/fade_animation.cpp b/Telegram/SourceFiles/ui/effects/fade_animation.cpp index 5e2663a5d..2c5cee26a 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/build/version b/Telegram/build/version index 209d05a04..41da4ebe3 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10009 +AppVersion 10010 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.9 -AppVersionStr 0.10.9 +AppVersionStrSmall 0.10.10 +AppVersionStr 0.10.10 AlphaChannel 0 BetaVersion 0 From c9288f2d0ad2f5f3d017faf2f30642eb668f7aff Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 18:07:50 +0300 Subject: [PATCH 17/32] Native notifications switched off by default. Libnotify supported. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/SourceFiles/facades.cpp | 4 +- Telegram/SourceFiles/facades.h | 2 +- Telegram/SourceFiles/localstorage.cpp | 15 +- .../platform/linux/linux_libnotify.cpp | 6 +- .../SourceFiles/platform/linux/linux_libs.cpp | 11 + .../SourceFiles/platform/linux/linux_libs.h | 15 + .../platform/linux/main_window_linux.cpp | 5 + .../platform/linux/main_window_linux.h | 4 +- .../linux/notifications_manager_linux.cpp | 339 ++++++++++++++---- .../linux/notifications_manager_linux.h | 6 + .../platform/win/main_window_win.cpp | 2 +- .../win/notifications_manager_win.cpp | 2 +- .../settings_notifications_widget.cpp | 17 +- .../settings/settings_notifications_widget.h | 4 +- 15 files changed, 348 insertions(+), 85 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5c67fe279..451ccb398 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -244,6 +244,7 @@ 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_sound_notify" = "Play sound"; "lng_settings_include_muted" = "Include muted chats in unread count"; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 01e3c90fb..3ebe4eec0 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -634,7 +634,7 @@ struct Data { bool RestoreSoundNotifyFromTray = false; bool IncludeMuted = true; DBINotifyView NotifyView = dbinvShowPreview; - bool WindowsNotifications = true; + bool NativeNotifications = false; base::Observable NotifySettingsChanged; DBIConnectionType ConnectionType = dbictAuto; @@ -741,7 +741,7 @@ DefineVar(Global, bool, DesktopNotify); DefineVar(Global, bool, RestoreSoundNotifyFromTray); DefineVar(Global, bool, IncludeMuted); DefineVar(Global, DBINotifyView, NotifyView); -DefineVar(Global, bool, WindowsNotifications); +DefineVar(Global, bool, NativeNotifications); DefineRefVar(Global, base::Observable, NotifySettingsChanged); DefineVar(Global, DBIConnectionType, ConnectionType); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 72d5699c2..4d2577e52 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -307,7 +307,7 @@ DeclareVar(bool, DesktopNotify); DeclareVar(bool, RestoreSoundNotifyFromTray); DeclareVar(bool, IncludeMuted); DeclareVar(DBINotifyView, NotifyView); -DeclareVar(bool, WindowsNotifications); +DeclareVar(bool, NativeNotifications); DeclareRefVar(base::Observable, NotifySettingsChanged); DeclareVar(DBIConnectionType, ConnectionType); diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 19dc70dcf..e8c6cc448 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -534,7 +534,7 @@ enum { dbiDcOption = 0x27, dbiTryIPv6 = 0x28, dbiSongVolume = 0x29, - dbiWindowsNotifications = 0x30, + dbiWindowsNotificationsOld = 0x30, dbiIncludeMuted = 0x31, dbiMegagroupSizeMax = 0x32, dbiDownloadPath = 0x33, @@ -548,6 +548,7 @@ enum { dbiModerateMode = 0x41, dbiVideoVolume = 0x42, dbiStickersRecentLimit = 0x43, + dbiNativeNotifications = 0x44, dbiEncryptedWithSalt = 333, dbiEncrypted = 444, @@ -989,12 +990,18 @@ 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); + Global::SetNativeNotifications(v == 1); } break; case dbiWorkMode: { @@ -1589,7 +1596,7 @@ 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(dbiAskDownloadPath) << qint32(Global::AskDownloadPath()); data.stream << quint32(dbiDownloadPath) << (Global::AskDownloadPath() ? QString() : Global::DownloadPath()) << (Global::AskDownloadPath() ? QByteArray() : Global::DownloadPathBookmark()); data.stream << quint32(dbiCompressPastedImage) << qint32(cCompressPastedImage()); diff --git a/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp index ddae19ce1..13cadc086 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp @@ -80,7 +80,11 @@ void startLibNotify() { QLibrary lib_notify; if (!loadLibrary(lib_notify, "notify", 4)) { - return; + if (!loadLibrary(lib_notify, "notify", 5)) { + if (!loadLibrary(lib_notify, "notify", 1)) { + return; + } + } } load(lib_notify, "notify_init", notify_init); diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.cpp b/Telegram/SourceFiles/platform/linux/linux_libs.cpp index 92185611e..110180a4c 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libs.cpp @@ -93,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!")); @@ -170,6 +176,7 @@ 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; @@ -193,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; diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.h b/Telegram/SourceFiles/platform/linux/linux_libs.h index 88f1e659c..a413dabe1 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.h +++ b/Telegram/SourceFiles/platform/linux/linux_libs.h @@ -255,6 +255,9 @@ inline gulong g_signal_connect_swapped_helper(gpointer instance, const gchar *de return g_signal_connect_data(instance, detailed_signal, c_handler, data, NULL, 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; @@ -324,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 9559058f5..42e825463 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" @@ -355,6 +356,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")); diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.h b/Telegram/SourceFiles/platform/linux/main_window_linux.h index a7cee027e..f5b2aa2e6 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.h +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.h @@ -58,9 +58,7 @@ public: void psUpdateCounter(); - bool psHasNativeNotifications() { - return false; - } + bool psHasNativeNotifications(); virtual QImage iconWithCounter(int size, int count, style::color bg, bool smallIcon) = 0; diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 5ef3467cf..961482bd4 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/notifications_utilities.h" #include "platform/linux/linux_libnotify.h" #include "platform/linux/linux_libs.h" +#include "lang.h" namespace Platform { namespace Notifications { @@ -31,7 +32,7 @@ namespace { NeverFreedPointer ManagerInstance; -bool supported() { +bool LibNotifyLoaded() { return (Libs::notify_init != nullptr) && (Libs::notify_uninit != nullptr) && (Libs::notify_is_initted != nullptr) @@ -43,7 +44,7 @@ bool supported() { && (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_timeout != nullptr) // && (Libs::notify_notification_set_category != nullptr) // && (Libs::notify_notification_set_urgency != nullptr) // && (Libs::notify_notification_set_icon_from_pixbuf != nullptr) @@ -52,23 +53,139 @@ bool supported() { // && (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_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_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, PeerId peerId, MsgId msgId) + : _data(Libs::notify_notification_new(title.toUtf8().constData(), body.toUtf8().constData(), nullptr)) + , _peerId(peerId) + , _msgId(msgId) { + if (valid()) { + init(); + } + } + 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() { + _handlerId = Libs::g_signal_connect_helper(Libs::g_object_cast(_data), "closed", G_CALLBACK(NotificationData::notificationClosed), this); + Libs::notify_notification_set_timeout(_data, Libs::NOTIFY_EXPIRES_DEFAULT); + + if (auto manager = ManagerInstance.data()) { + if (manager->hasActionsSupport()) { + Libs::notify_notification_add_action(_data, "default", lang(lng_context_reply_msg).toUtf8().constData(), NotificationData::notificationClicked, this, nullptr); + } + } + } + void onClose() { + if (auto manager = ManagerInstance.data()) { + manager->clearNotification(_peerId, _msgId); + } + } + void onClick() { + if (auto manager = ManagerInstance.data()) { + manager->notificationActivated(_peerId, _msgId); + } + } + + 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); + } + + static void notificationClosed(Libs::NotifyNotification *notification, gpointer data) { + static_cast(data)->onClose(); + } + static void notificationClicked(Libs::NotifyNotification *notification, char *action, gpointer data) { + static_cast(data)->onClick(); + } + + Libs::NotifyNotification *_data = nullptr; + PeerId _peerId = 0; + MsgId _msgId = 0; + gulong _handlerId = 0; + +}; + +using Notification = QSharedPointer; + } // namespace void start() { - if (supported()) { + if (LibNotifyLoaded()) { if (Libs::notify_is_initted() || Libs::notify_init("Telegram Desktop")) { ManagerInstance.makeIfNull(); } @@ -76,7 +193,14 @@ void start() { } Manager *manager() { - return ManagerInstance.data(); + if (Global::NativeNotifications()) { + return ManagerInstance.data(); + } + return nullptr; +} + +bool supported() { + return ManagerInstance.data() != nullptr; } void finish() { @@ -88,131 +212,214 @@ void finish() { class Manager::Impl { public: + Impl(); + void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); void clearAll(); void clearFromHistory(History *history); + void clearNotification(PeerId peerId, MsgId msgId); + + bool hasPoorSupport() const { + return _poorSupported; + } + bool hasActionsSupport() const { + return _actionsSupported; + } private: - static void notificationClosed(Libs::NotifyNotification *notification, gpointer data); - void clearNotification(Libs::NotifyNotification *notification); + void showNextNotification(); - using Notifications = QMap>; + struct QueuedNotification { + PeerData *peer = nullptr; + MsgId msgId = 0; + QString title; + QString body; + bool showUserpic = false; + }; + + using QueuedNotifications = QList; + QueuedNotifications _queuedNotifications; + + using Notifications = QMap>; Notifications _notifications; - using NotificationsData = QMap>; - NotificationsData _notificationsData; - Window::Notifications::CachedUserpics _cachedUserpics; + bool _actionsSupported = false; + bool _poorSupported = true; }; -void Manager::Impl::notificationClosed(Libs::NotifyNotification *notification, gpointer data) { - if (auto manager = ManagerInstance.data()) { - manager->_impl->clearNotification(notification); - } +void FreeCapability(void *ptr, void *data) { + Libs::g_free(ptr); } -void Manager::Impl::clearNotification(Libs::NotifyNotification *notification) { - auto dataIt = _notificationsData.find(notification); - if (dataIt == _notificationsData.cend()) { - return; +Manager::Impl::Impl() { + if (auto capabilities = Libs::notify_get_server_caps()) { + for (auto capability = capabilities; capability; capability = capability->next) { + if (QString::fromUtf8(static_cast(capability->data)) == qstr("actions")) { + _actionsSupported = true; + break; + } + } + Libs::g_list_free_full(capabilities, g_free); + Libs::g_list_free(capabilities); } - auto peerId = dataIt->first; - auto msgId = dataIt->second; - _notificationsData.erase(dataIt); - - auto i = _notifications.find(peerId); - if (i != _notifications.cend()) { - auto it = i.value().find(msgId); - if (it != i.value().cend()) { - Libs::g_object_unref(Libs::g_object_cast(it.value())); - i.value().erase(it); - if (i.value().isEmpty()) { - _notifications.erase(i); + // 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) { + auto serverName = QString::fromUtf8(static_cast(name)); + LOG(("Notifications Server: %1").arg(serverName)); + if (serverName == qstr("notify-osd")) { + _actionsSupported = false; } + Libs::g_free(name); } } + if (!_actionsSupported) { + _poorSupported = true; + } } void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - auto titleUtf8 = title.toUtf8(); - auto bodyUtf8 = (subtitle.isEmpty() ? msg : ("" + subtitle + "\n" + msg)).toUtf8(); - auto notification = Libs::notify_notification_new(titleUtf8.constData(), bodyUtf8.constData(), nullptr); - if (!notification) { + auto titleText = escapeNotificationHtml(title); + auto bodyText = subtitle.isEmpty() ? escapeNotificationHtml(msg) : ("" + escapeNotificationHtml(subtitle) + "\n" + escapeNotificationHtml(msg)); + + QueuedNotification notification; + notification.peer = peer; + notification.msgId = msgId; + notification.title = titleText; + notification.body = bodyText; + notification.showUserpic = showUserpic; + _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; } - Libs::g_signal_connect_helper(Libs::g_object_cast(notification), "closed", G_CALLBACK(Manager::Impl::notificationClosed), peer); + auto peerId = data.peer->id; + auto msgId = data.msgId; + auto notification = MakeShared(data.title, data.body, peerId, msgId); + if (!notification->valid()) { + return; + } StorageKey key; - if (showUserpic) { - key = peer->userpicUniqueKey(); + if (data.showUserpic) { + key = data.peer->userpicUniqueKey(); } else { key = StorageKey(0, 0); } - auto userpicPath = _cachedUserpics.get(key, peer); - auto userpicPathNative = QFile::encodeName(userpicPath); - if (auto pixbuf = Libs::gdk_pixbuf_new_from_file(userpicPathNative.constData(), nullptr)) { - Libs::notify_notification_set_image_from_pixbuf(notification, pixbuf); - Libs::g_object_unref(Libs::g_object_cast(pixbuf)); - } + notification->setImage(_cachedUserpics.get(key, data.peer)); - auto i = _notifications.find(peer->id); + 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); - _notificationsData.remove(oldNotification); - Libs::notify_notification_close(oldNotification, nullptr); - Libs::g_object_unref(Libs::g_object_cast(oldNotification)); - i = _notifications.find(peer->id); + oldNotification->close(); + i = _notifications.find(peerId); } } if (i == _notifications.cend()) { - i = _notifications.insert(peer->id, QMap()); + i = _notifications.insert(peerId, QMap()); } - auto result = Libs::notify_notification_show(notification, nullptr); - if (!result) { - Libs::g_object_unref(Libs::g_object_cast(notification)); - i = _notifications.find(peer->id); - if (i != _notifications.cend() && i->isEmpty()) _notifications.erase(i); - return; + _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(); } - _notifications[peer->id].insert(msgId, notification); - _notificationsData.insert(notification, qMakePair(peer->id, msgId)); } void Manager::Impl::clearAll() { - _notificationsData.clear(); + _queuedNotifications.clear(); auto temp = createAndSwap(_notifications); for_const (auto ¬ifications, temp) { for_const (auto notification, notifications) { - Libs::notify_notification_close(notification, nullptr); - Libs::g_object_unref(Libs::g_object_cast(notification)); + 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 = createAndSwap(i.value()); _notifications.erase(i); for_const (auto notification, temp) { - _notificationsData.remove(notification); - Libs::notify_notification_close(notification, nullptr); - Libs::g_object_unref(Libs::g_object_cast(notification)); + 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()) { } +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, bool showUserpic, const QString &msg, bool showReplyButton) { diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h index e7b7e0683..38672584a 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -29,6 +29,7 @@ class Manager; void start(); Manager *manager(); +bool supported(); void finish(); inline void defaultNotificationShown(QWidget *widget) { @@ -37,6 +38,11 @@ inline void defaultNotificationShown(QWidget *widget) { class Manager : public Window::Notifications::NativeManager { public: Manager(); + + void clearNotification(PeerId peerId, MsgId msgId); + bool hasPoorSupport() const; + bool hasActionsSupport() const; + ~Manager(); protected: diff --git a/Telegram/SourceFiles/platform/win/main_window_win.cpp b/Telegram/SourceFiles/platform/win/main_window_win.cpp index 7294ef2be..489e7b637 100644 --- a/Telegram/SourceFiles/platform/win/main_window_win.cpp +++ b/Telegram/SourceFiles/platform/win/main_window_win.cpp @@ -21,7 +21,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "stdafx.h" #include "platform/win/main_window_win.h" -#include "platform/win/notifications_manager_win.h" +#include "platform/platform_notifications_manager.h" #include "platform/win/windows_dlls.h" #include "window/notifications_manager.h" #include "mainwindow.h" diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 417f18604..c5746d3a3 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -321,7 +321,7 @@ void start() { } Manager *manager() { - if (Global::WindowsNotifications()) { + if (Global::NativeNotifications()) { return ManagerInstance.data(); } return nullptr; diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 6dd4b8f93..03370744b 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -60,11 +60,20 @@ void NotificationsWidget::createControls() { } addChildRow(_playSound, margin, lang(lng_settings_sound_notify), SLOT(onPlaySound()), Global::SoundNotify()); addChildRow(_includeMuted, margin, lang(lng_settings_include_muted), SLOT(onIncludeMuted()), Global::IncludeMuted()); + + QString nativeNotificationsLabel; #ifdef Q_OS_WIN if (App::wnd()->psHasNativeNotifications()) { - addChildRow(_windowsNative, margin, lang(lng_settings_use_windows), SLOT(onWindowsNative()), Global::WindowsNotifications()); + 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()); + } } void NotificationsWidget::onDesktopNotifications() { @@ -132,13 +141,13 @@ void NotificationsWidget::viewParamUpdated() { } } -void NotificationsWidget::onWindowsNative() { - if (Global::WindowsNotifications() == _windowsNative->checked()) { +void NotificationsWidget::onNativeNotifications() { + if (Global::NativeNotifications() == _nativeNotifications->checked()) { return; } Window::Notifications::manager()->clearAllFast(); - Global::SetWindowsNotifications(_windowsNative->checked()); + Global::SetNativeNotifications(_nativeNotifications->checked()); Local::writeUserSettings(); } diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.h b/Telegram/SourceFiles/settings/settings_notifications_widget.h index 7625a76b7..3c68f1c34 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.h +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.h @@ -34,7 +34,7 @@ private slots: void onDesktopNotifications(); void onShowSenderName(); void onShowMessagePreview(); - void onWindowsNative(); + void onNativeNotifications(); void onPlaySound(); void onIncludeMuted(); @@ -46,7 +46,7 @@ private: ChildWidget _desktopNotifications = { nullptr }; ChildWidget> _showSenderName = { nullptr }; ChildWidget> _showMessagePreview = { nullptr }; - ChildWidget _windowsNative = { nullptr }; + ChildWidget _nativeNotifications = { nullptr }; ChildWidget _playSound = { nullptr }; ChildWidget _includeMuted = { nullptr }; From b600050057f0d0de5dc9d3c4fbae1f9dab5127ec Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 18:00:54 +0300 Subject: [PATCH 18/32] Version 0.10.11: two more crash fixes. --- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/boxes/report_box.cpp | 2 +- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/SourceFiles/history/history_message.cpp | 12 +++++++----- Telegram/build/version | 6 +++--- 6 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 2b84c45ad..1b2a0fdd7 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,10,0 - PRODUCTVERSION 0,10,10,0 + FILEVERSION 0,10,11,0 + PRODUCTVERSION 0,10,11,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.10.0" + VALUE "FileVersion", "0.10.11.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.10.0" + VALUE "ProductVersion", "0.10.11.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 3a100ee90..def0bd48c 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,10,0 - PRODUCTVERSION 0,10,10,0 + FILEVERSION 0,10,11,0 + PRODUCTVERSION 0,10,11,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.10.0" + VALUE "FileVersion", "0.10.11.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.10.0" + VALUE "ProductVersion", "0.10.11.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/boxes/report_box.cpp b/Telegram/SourceFiles/boxes/report_box.cpp index e845390cc..42cb287ff 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/core/version.h b/Telegram/SourceFiles/core/version.h index 16c522220..5c49b9b9d 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10010; -constexpr str_const AppVersionStr = "0.10.10"; +constexpr int AppVersion = 10011; +constexpr str_const AppVersionStr = "0.10.11"; constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index dc23b998d..b6f0c4bd5 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -2011,10 +2011,11 @@ bool HistoryService::prepareGameScoreText(const QString &from, QString *outText, } else { gameTitle = lang(lng_deleted_message); } + auto scoreNumber = gamescore ? gamescore->score : 0; if (_from->isSelf()) { - *outText = lng_action_game_you_scored(lt_count, gamescore->score, lt_game, gameTitle); + *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); + *outText = lng_action_game_score(lt_from, from, lt_count, scoreNumber, lt_game, gameTitle); } if (second) { outLinks->push_back(second); @@ -2212,12 +2213,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/build/version b/Telegram/build/version index 41da4ebe3..6eec02a3c 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10010 +AppVersion 10011 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.10 -AppVersionStr 0.10.10 +AppVersionStrSmall 0.10.11 +AppVersionStr 0.10.11 AlphaChannel 0 BetaVersion 0 From 9fdd75113f3b9e0265163938a032ebf94983a26d Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 3 Oct 2016 18:45:52 +0300 Subject: [PATCH 19/32] Bump version to 0.10.11. --- Telegram/Resources/winrc/Telegram.rc | 8 ++++---- Telegram/Resources/winrc/Updater.rc | 8 ++++---- Telegram/SourceFiles/core/version.h | 4 ++-- Telegram/build/version | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 2b84c45ad..1b2a0fdd7 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,10,0 - PRODUCTVERSION 0,10,10,0 + FILEVERSION 0,10,11,0 + PRODUCTVERSION 0,10,11,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.10.0" + VALUE "FileVersion", "0.10.11.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.10.0" + VALUE "ProductVersion", "0.10.11.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 3a100ee90..def0bd48c 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,10,0 - PRODUCTVERSION 0,10,10,0 + FILEVERSION 0,10,11,0 + PRODUCTVERSION 0,10,11,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.10.0" + VALUE "FileVersion", "0.10.11.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.10.0" + VALUE "ProductVersion", "0.10.11.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 16c522220..5c49b9b9d 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10010; -constexpr str_const AppVersionStr = "0.10.10"; +constexpr int AppVersion = 10011; +constexpr str_const AppVersionStr = "0.10.11"; constexpr bool AppAlphaVersion = false; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/build/version b/Telegram/build/version index 41da4ebe3..6eec02a3c 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10010 +AppVersion 10011 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.10 -AppVersionStr 0.10.10 +AppVersionStrSmall 0.10.11 +AppVersionStr 0.10.11 AlphaChannel 0 BetaVersion 0 From c8aa7672e9655fd962533f768d7d83e2d092f686 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 4 Oct 2016 16:36:50 +0300 Subject: [PATCH 20/32] Notifications by libnotify support improved. --- .../platform/linux/linux_libnotify.cpp | 56 +++---- .../platform/linux/linux_libnotify.h | 56 +++---- .../SourceFiles/platform/linux/linux_libs.h | 8 +- .../linux/notifications_manager_linux.cpp | 153 ++++++++++++------ .../linux/notifications_manager_linux.h | 2 + .../window/notifications_manager.cpp | 1 - 6 files changed, 165 insertions(+), 111 deletions(-) diff --git a/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp index 13cadc086..23ba37b4e 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_libnotify.cpp @@ -48,28 +48,28 @@ bool loadLibrary(QLibrary &lib, const char *name, int version) { 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_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_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_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_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 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_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; @@ -90,28 +90,28 @@ void startLibNotify() { 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_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_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_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_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", 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_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); diff --git a/Telegram/SourceFiles/platform/linux/linux_libnotify.h b/Telegram/SourceFiles/platform/linux/linux_libnotify.h index e59431ffe..9cde80d7c 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libnotify.h +++ b/Telegram/SourceFiles/platform/linux/linux_libnotify.h @@ -52,11 +52,11 @@ 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_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_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; @@ -67,53 +67,53 @@ 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_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_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_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_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_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 = 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_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_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_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 = 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_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_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; diff --git a/Telegram/SourceFiles/platform/linux/linux_libs.h b/Telegram/SourceFiles/platform/linux/linux_libs.h index a413dabe1..3b542a407 100644 --- a/Telegram/SourceFiles/platform/linux/linux_libs.h +++ b/Telegram/SourceFiles/platform/linux/linux_libs.h @@ -247,12 +247,12 @@ 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); diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 961482bd4..3e0fd4fce 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -41,7 +41,7 @@ bool LibNotifyLoaded() { && (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_update != nullptr) && (Libs::notify_notification_show != nullptr) // && (Libs::notify_notification_set_app_name != nullptr) && (Libs::notify_notification_set_timeout != nullptr) @@ -80,12 +80,10 @@ QString escapeNotificationHtml(QString text) { class NotificationData { public: - NotificationData(const QString &title, const QString &body, PeerId peerId, MsgId msgId) - : _data(Libs::notify_notification_new(title.toUtf8().constData(), body.toUtf8().constData(), nullptr)) - , _peerId(peerId) - , _msgId(msgId) { + 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(); + init(capabilities, peerId, msgId); } } bool valid() const { @@ -131,51 +129,80 @@ public: ~NotificationData() { if (valid()) { - if (_handlerId > 0) { - Libs::g_signal_handler_disconnect(Libs::g_object_cast(_data), _handlerId); - } - Libs::notify_notification_clear_actions(_data); +// 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() { - _handlerId = Libs::g_signal_connect_helper(Libs::g_object_cast(_data), "closed", G_CALLBACK(NotificationData::notificationClosed), this); + 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()) { - Libs::notify_notification_add_action(_data, "default", lang(lng_context_reply_msg).toUtf8().constData(), NotificationData::notificationClicked, this, nullptr); + auto label = lang(lng_context_reply_msg).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 onClose() { - if (auto manager = ManagerInstance.data()) { - manager->clearNotification(_peerId, _msgId); - } - } - void onClick() { - if (auto manager = ManagerInstance.data()) { - manager->notificationActivated(_peerId, _msgId); - } - } 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) { - static_cast(data)->onClose(); + 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) { - static_cast(data)->onClick(); + auto notificationData = static_cast(data); + if (auto manager = ManagerInstance.data()) { + manager->notificationActivated(notificationData->peerId, notificationData->msgId); + } } Libs::NotifyNotification *_data = nullptr; - PeerId _peerId = 0; - MsgId _msgId = 0; gulong _handlerId = 0; }; @@ -188,6 +215,12 @@ 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!")); } } } @@ -212,7 +245,7 @@ void finish() { class Manager::Impl { public: - Impl(); + bool init(); void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); void clearAll(); @@ -237,6 +270,9 @@ private: bool showUserpic = false; }; + QString _serverName; + QStringList _capabilities; + using QueuedNotifications = QList; QueuedNotifications _queuedNotifications; @@ -245,24 +281,27 @@ private: Window::Notifications::CachedUserpics _cachedUserpics; bool _actionsSupported = false; - bool _poorSupported = true; + bool _markupSupported = false; + bool _poorSupported = false; }; -void FreeCapability(void *ptr, void *data) { - Libs::g_free(ptr); -} - -Manager::Impl::Impl() { +bool Manager::Impl::init() { if (auto capabilities = Libs::notify_get_server_caps()) { for (auto capability = capabilities; capability; capability = capability->next) { - if (QString::fromUtf8(static_cast(capability->data)) == qstr("actions")) { - _actionsSupported = true; - break; - } - } - Libs::g_list_free_full(capabilities, g_free); - Libs::g_list_free(capabilities); + 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 @@ -270,22 +309,32 @@ Manager::Impl::Impl() { gchar *name = nullptr; if (Libs::notify_get_server_info(&name, nullptr, nullptr, nullptr)) { if (name) { - auto serverName = QString::fromUtf8(static_cast(name)); - LOG(("Notifications Server: %1").arg(serverName)); - if (serverName == qstr("notify-osd")) { + _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; } - Libs::g_free(name); + } else { + LOG(("LibNotify Error: successfully got empty server name!")); } + } else { + LOG(("LibNotify Error: could not get server name!")); } - if (!_actionsSupported) { - _poorSupported = true; - } + + return !_serverName.isEmpty(); } void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { auto titleText = escapeNotificationHtml(title); - auto bodyText = subtitle.isEmpty() ? escapeNotificationHtml(msg) : ("" + escapeNotificationHtml(subtitle) + "\n" + escapeNotificationHtml(msg)); + 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; @@ -323,7 +372,7 @@ void Manager::Impl::showNextNotification() { auto peerId = data.peer->id; auto msgId = data.msgId; - auto notification = MakeShared(data.title, data.body, peerId, msgId); + auto notification = MakeShared(data.title, data.body, _capabilities, peerId, msgId); if (!notification->valid()) { return; } @@ -408,6 +457,10 @@ void Manager::Impl::clearNotification(PeerId peerId, MsgId msgId) { Manager::Manager() : _impl(std_::make_unique()) { } +bool Manager::init() { + return _impl->init(); +} + void Manager::clearNotification(PeerId peerId, MsgId msgId) { _impl->clearNotification(peerId, msgId); } diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h index 38672584a..8b52c6328 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -39,6 +39,8 @@ class Manager : public Window::Notifications::NativeManager { public: Manager(); + bool init(); + void clearNotification(PeerId peerId, MsgId msgId); bool hasPoorSupport() const; bool hasActionsSupport() const; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index f0c7ed0fb..e72a81336 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -51,7 +51,6 @@ 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(); From 043cba0a6411db8a7b4fe5c77ed5ee81310b4486 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 4 Oct 2016 21:18:08 +0300 Subject: [PATCH 21/32] Custom notifications inline reply added, positioning broken. --- Telegram/Resources/basic.style | 25 +- .../Resources/icons/fade_horizontal_left.png | Bin 0 -> 139 bytes .../icons/fade_horizontal_left@2x.png | Bin 0 -> 192 bytes .../Resources/icons/fade_horizontal_right.png | Bin 0 -> 142 bytes .../icons/fade_horizontal_right@2x.png | Bin 0 -> 190 bytes .../Resources/icons/notification_send.png | Bin 0 -> 292 bytes .../Resources/icons/notification_send@2x.png | Bin 0 -> 506 bytes Telegram/Resources/langs/lang.strings | 2 + Telegram/SourceFiles/dialogswidget.cpp | 4 +- .../history/field_autocomplete.cpp | 4 +- Telegram/SourceFiles/media/media_audio.cpp | 4 +- .../linux/notifications_manager_linux.cpp | 2 +- .../platform/mac/notifications_manager_mac.mm | 1 + Telegram/SourceFiles/stickers/emoji_pan.cpp | 6 +- .../window/notifications_manager_default.cpp | 216 ++++++++++++++---- .../window/notifications_manager_default.h | 43 +++- .../window/notifications_utilities.cpp | 1 + Telegram/SourceFiles/window/window.style | 69 ++++++ Telegram/gyp/Telegram.gyp | 3 + 19 files changed, 300 insertions(+), 80 deletions(-) create mode 100644 Telegram/Resources/icons/fade_horizontal_left.png create mode 100644 Telegram/Resources/icons/fade_horizontal_left@2x.png create mode 100644 Telegram/Resources/icons/fade_horizontal_right.png create mode 100644 Telegram/Resources/icons/fade_horizontal_right@2x.png create mode 100644 Telegram/Resources/icons/notification_send.png create mode 100644 Telegram/Resources/icons/notification_send@2x.png create mode 100644 Telegram/SourceFiles/window/window.style diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style index 3685b2be2..e5c8eae10 100644 --- a/Telegram/Resources/basic.style +++ b/Telegram/Resources/basic.style @@ -1400,15 +1400,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); @@ -1417,17 +1409,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); @@ -2031,7 +2012,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; @@ -2045,6 +2026,8 @@ webPageDescriptionFont: normalFont; webPagePhotoSize: 100px; webPagePhotoDelta: 8px; +mediaPlayerSuppressDuration: 150; + botDescSkip: 8px; suppressAll: 0.2; diff --git a/Telegram/Resources/icons/fade_horizontal_left.png b/Telegram/Resources/icons/fade_horizontal_left.png new file mode 100644 index 0000000000000000000000000000000000000000..93db9ad4ce371f39fd63c99c8af186b27e4815ff GIT binary patch literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^8bHj*!3HGP#J-sfq=GzM978x}hW0q}9Wmfxdij68 z^linmrs|u$Axi`gw=Ul;z5mbF-TIRhIG@XS9J=>ADD;F+irOl!V!sJ{e1!xH3(H+t o&b-MpX7=nc+;FXFcfDQQ=Js6S4_7PFfu=Kfy85}Sb4q9e0Mq_4%K!iX literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d4e9f55a11f2b970b3267ce076226729d3ba69cd GIT binary patch literal 192 zcmeAS@N?(olHy`uVBq!ia0vp^0YJ>e!3HGHhernjsdi5n#}JK)Qv;*9SPVJ3_x^9K zO|utEUA8$^!qMbdm`96BVaMDopQ57UDuJQfXU**2m+j(n_RPs+@9b`znK0A9*o8%j z=^dZ(Y+GaLxX||f``*r6rDU96z4!8+uh;rkbG=rPW9T?x|EqKkkL6uuPC?1!UG>s` r-(L-3h{&#WjqsPOJ6pDH)dxoQ%y&FydB<-7oy6ej>gTe~DWM4fMWINA literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/fade_horizontal_right.png b/Telegram/Resources/icons/fade_horizontal_right.png new file mode 100644 index 0000000000000000000000000000000000000000..f10b4f924644713a9cc976b8405651cbce2ca3ee GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^8bHj*!3HGP#J-sfq(VJi978x}`kt}oV^-i{xp=T4 zvVO<^!pT}1M=xj0mVNhcqKk_{=c-3@4(}EBEHMvtO}lhA<=JifNk9H~aD2PB!}{I1 sd$YG*OHMmuX=r?=$M6{Q9;O<`Yp0q28NX8!1X{r0>FVdQ&MBb@02OIAv;Y7A literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..ed229a5b7903aa815c482fd391469ed046add8b8 GIT binary patch literal 190 zcmV;v073tWP)F|38d-s1jwi&Y_kNwrsH&Nx3^nf+VU65pmIDjK!-8nTavR!OP4;X3x!8 z)1TSQyzHtfkX*TWPeiODiFvoXBO+EevkTw*UI1?Ojqyzu;%-KKdfARLm2fhs?{hwP+O#lD@07*qoM6N<$g7qI!xBvhE literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/notification_send.png b/Telegram/Resources/icons/notification_send.png new file mode 100644 index 0000000000000000000000000000000000000000..f7f6bd47d8b536ffb5c0339c5fe6c5ceaf21ab03 GIT binary patch literal 292 zcmV+<0o(qGP)2!8?oB%yawA#&#c0000AN^}X0#P2@bJ7M>lb<@e|g8~0N ze0mN#4vxno&1N%dwORzg-f_8Hh=?eTV_Ga0)a`cbmnss~D5Yq#+0bM%sb8*0G>eqd zo?6_s%n-*h&FAxaYw?We?^=w6s_0mabWobyVhrIc7Mm)LH%P)a>7`UuYX-J2+rMv^25!w^9bAW4$)qD54Z zhEfXq{T`m@!7(AJaU2JZadWWcpF literal 0 HcmV?d00001 diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 451ccb398..b1e8b1ff7 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -872,6 +872,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "Could not send a file, because it is larger than 1.5 GB :("; "lng_send_folder" = "Could not send «{name}» because it is a directory :("; +"lng_notification_reply" = "Reply"; + "lng_forward_choose" = "Choose recipient..."; "lng_forward_cant" = "Sorry, no way to forward here :("; "lng_forward_confirm" = "Forward to {recipient}?"; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 3b94f1d27..66778d0f8 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -123,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); diff --git a/Telegram/SourceFiles/history/field_autocomplete.cpp b/Telegram/SourceFiles/history/field_autocomplete.cpp index df5f5a7b6..5ef830b47 100644 --- a/Telegram/SourceFiles/history/field_autocomplete.cpp +++ b/Telegram/SourceFiles/history/field_autocomplete.cpp @@ -600,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/media/media_audio.cpp b/Telegram/SourceFiles/media/media_audio.cpp index 8a3854e08..e947181b1 100644 --- a/Telegram/SourceFiles/media/media_audio.cpp +++ b/Telegram/SourceFiles/media/media_audio.cpp @@ -984,13 +984,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/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 3e0fd4fce..6ff08d77a 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -156,7 +156,7 @@ private: if (auto manager = ManagerInstance.data()) { if (manager->hasActionsSupport()) { - auto label = lang(lng_context_reply_msg).toUtf8(); + auto label = lang(lng_notification_reply).toUtf8(); auto actionReceiver = _data; auto actionHandler = &NotificationData::notificationClicked; auto actionLabel = label.constData(); diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index 831fce549..c92db9c02 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "pspecific.h" #include "platform/mac/mac_utilities.h" +#include "styles/style_window.h" #include diff --git a/Telegram/SourceFiles/stickers/emoji_pan.cpp b/Telegram/SourceFiles/stickers/emoji_pan.cpp index d515e3506..900ea04da 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.cpp +++ b/Telegram/SourceFiles/stickers/emoji_pan.cpp @@ -2419,14 +2419,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 +2444,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]() { diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 5d331b4b7..f0b57d975 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -24,8 +24,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #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 { @@ -37,6 +39,16 @@ constexpr int kNotifyWindowsCount = 3; NeverFreedPointer ManagerInstance; +int notificationWidth() { + static auto result = ([] { + auto replyWidth = st::defaultBoxButton.font->width(lang(lng_notification_reply).toUpper()) - st::defaultBoxButton.width; + auto textLeft = st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft; + auto minWidth = textLeft + replyWidth + st::boxButtonPadding.right(); + return qMax(st::notifyMinWidth, minWidth); + })(); + return result; +} + } // namespace void start() { @@ -78,7 +90,7 @@ void Manager::showNextFromQueue() { int count = kNotifyWindowsCount; for_const (auto widget, _widgets) { - if (widget->index() < 0) continue; + if (widget->isUnlinked()) continue; --count; } if (count <= 0) { @@ -86,8 +98,8 @@ void Manager::showNextFromQueue() { } auto r = psDesktopRect(); - auto x = r.x() + r.width() - st::notifyWidth - st::notifyDeltaX; - auto y = r.y() + r.height() - st::notifyHeight - st::notifyDeltaY; + auto x = r.x() + r.width() - notificationWidth() - st::notifyDeltaX; + auto y = r.y() + r.height(); do { auto queued = _queuedNotifications.front(); _queuedNotifications.pop_front(); @@ -98,11 +110,11 @@ void Manager::showNextFromQueue() { --count; } while (count > 0 && !_queuedNotifications.isEmpty()); - auto shown = kNotifyWindowsCount - count; + auto bottom = y - st::notifyDeltaY; for_const (auto widget, _widgets) { - if (widget->index() < 0) continue; - --shown; - widget->moveTo(x, y - shown * (st::notifyHeight + st::notifyDeltaY)); + if (widget->isUnlinked() < 0) continue; + widget->moveTop(y - widget->height(), y); + y -= widget->height() + st::notifyDeltaY; } } @@ -177,12 +189,16 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem * , _started(GetTickCount()) #endif // Q_OS_WIN && !Q_OS_WINRT , _close(this, st::notifyClose) +, _reply(this, lang(lng_notification_reply), st::defaultBoxButton) , _alphaDuration(st::notifyFastAnim) -, _posDuration(st::notifyFastAnim) , a_opacity(0) , a_func(anim::linear) -, a_y(y + st::notifyHeight + st::notifyDeltaY) +, a_top(y) +, a_bottom(y + st::notifyMinHeight) +, _a_movement(animation(this, &Widget::step_movement)) , _a_appearance(animation(this, &Widget::step_appearance)) { + setGeometry(x, a_top.current(), notificationWidth(), a_bottom.current() - a_top.current()); + updateNotifyDisplay(); _hideTimer.setSingleShot(true); @@ -191,15 +207,21 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem * _inputTimer.setSingleShot(true); connect(&_inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); - _close.setClickedCallback([this] { + _close->setClickedCallback([this] { unlinkHistoryAndNotify(); }); - _close.setAcceptBoth(true); - _close.move(st::notifyWidth - st::notifyClose.width - st::notifyClosePos.x(), st::notifyClosePos.y()); - _close.show(); + _close->setAcceptBoth(true); + _close->moveToRight(st::notifyClosePos.x(), st::notifyClosePos.y()); + _close->show(); - a_y.start(y); - setGeometry(x, a_y.current(), st::notifyWidth, st::notifyHeight); + _reply->setClickedCallback([this] { + showReplyField(); + }); + _replyPadding = st::notifyMinHeight - st::notifyPhotoPos.y() - st::notifyPhotoSize; + _reply->moveToRight(_replyPadding, height() - _reply->height() - _replyPadding); + _reply->hide(); + + prepareActionsCache(); a_opacity.start(1); setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); @@ -209,12 +231,29 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem * setWindowOpacity(a_opacity.current()); - _alphaDuration = _posDuration = st::notifyFastAnim; + _alphaDuration = st::notifyFastAnim; _a_appearance.start(); checkLastInput(); } +void Widget::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.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)); +} + void Widget::checkLastInput() { #if defined Q_OS_WIN && !defined Q_OS_WINRT LASTINPUTINFO lii; @@ -235,24 +274,39 @@ void Widget::checkLastInput() { #endif // else for Q_OS_WIN && !Q_OS_WINRT } -void Widget::moveTo(int x, int y, int index) { - if (index >= 0) { - _index = index; +void Widget::onReplyResize() { + _a_movement.stop(); + auto newHeight = st::notifyMinHeight + _replyArea->height() + st::notifyBorderWidth; + auto delta = height() - newHeight; + if (delta != 0) { + auto top = a_top.current() + delta; + a_top = anim::ivalue(top, top); + setGeometry(x(), top, width(), a_bottom.current() - top); + update(); } - move(x, a_y.current()); - a_y.start(y); - a_opacity.restart(); - _posDuration = st::notifyFastAnim; - _a_appearance.start(); +} + +void Widget::onReplySubmit(bool ctrlShiftEnter) { + sendReply(); +} + +void Widget::onReplyCancel() { + unlinkHistoryAndNotify(); +} + +void Widget::moveTop(int top, int bottom) { + a_top.start(top); + a_bottom.start(bottom); + _a_movement.start(); } void Widget::updateNotifyDisplay() { if (!_history || !_peer || (!_item && _forwardedCount < 2)) return; - int32 w = st::notifyWidth, h = st::notifyHeight; + 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); + img.fill(st::notifyBg->c); { Painter p(&img); @@ -345,6 +399,64 @@ void Widget::unlinkHistoryAndNotify() { } } +void Widget::toggleActionButtons(bool visible) { + if (_actionsVisible != visible) { + _actionsVisible = visible; + _reply->hide(); + a_actionsOpacity.start([this] { actionsOpacityCallback(); }, _actionsVisible ? 0. : 1., _actionsVisible ? 1. : 0., st::notifyActionsDuration); + } +} + +void Widget::actionsOpacityCallback() { + update(); + if (!a_actionsOpacity.animating() && _actionsVisible) { + _reply->show(); + } +} + +void Widget::showReplyField() { + if (_replyArea) return; + + _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); + + a_top.finish(); + a_bottom.finish(); + + _a_movement.stop(); + auto top = a_top.current() - _replyArea->height() - st::notifyBorderWidth; + auto bottom = a_top.current() + st::notifyMinHeight; + a_top = anim::ivalue(top, top); + a_bottom = anim::ivalue(bottom, bottom); + setGeometry(x(), top, width(), bottom - top); + update(); +} + +void Widget::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()); + } +} + void Widget::unlinkHistory(History *history) { if (!history || history == _history) { animHide(st::notifyFastAnim, anim::linear); @@ -358,6 +470,9 @@ void Widget::enterEvent(QEvent *e) { if (auto manager = ManagerInstance.data()) { manager->stopAllHiding(); } + if (!_replyArea) { + toggleActionButtons(true); + } } void Widget::leaveEvent(QEvent *e) { @@ -365,6 +480,7 @@ void Widget::leaveEvent(QEvent *e) { if (auto manager = ManagerInstance.data()) { manager->startAllHiding(); } + toggleActionButtons(false); } void Widget::startHiding() { @@ -387,8 +503,27 @@ void Widget::mousePressEvent(QMouseEvent *e) { } void Widget::paintEvent(QPaintEvent *e) { - QPainter p(this); + Painter p(this); 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); + } + + if (height() > st::notifyMinHeight) { + auto replyAreaHeight = height() - st::notifyMinHeight - st::notifyBorderWidth; + if (replyAreaHeight > 0) { + p.fillRect(st::notifyBorderWidth, st::notifyMinHeight, width() - 2 * st::notifyBorderWidth, replyAreaHeight, st::notifyBg); + } + p.fillRect(0, st::notifyMinHeight, st::notifyBorderWidth, height() - st::notifyMinHeight, st::notifyBorder); + p.fillRect(width() - st::notifyBorderWidth, st::notifyMinHeight, st::notifyBorderWidth, height() - st::notifyMinHeight, st::notifyBorder); + p.fillRect(st::notifyBorderWidth, height() - st::notifyBorderWidth, width() - 2 * st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder); + } } void Widget::animHide(float64 duration, anim::transition func) { @@ -396,7 +531,6 @@ void Widget::animHide(float64 duration, anim::transition func) { _alphaDuration = duration; a_func = func; a_opacity.start(0); - a_y.restart(); _hiding = true; _a_appearance.start(); } @@ -406,7 +540,6 @@ void Widget::stopHiding() { _alphaDuration = st::notifyFastAnim; a_func = anim::linear; a_opacity.start(1); - a_y.restart(); _hiding = false; _hideTimer.stop(); _a_appearance.start(); @@ -418,25 +551,30 @@ void Widget::hideByTimer() { } void Widget::step_appearance(float64 ms, bool timer) { - float64 dtAlpha = ms / _alphaDuration, dtPos = ms / _posDuration; - if (dtAlpha >= 1) { + float64 dt = ms / float64(_alphaDuration); + if (dt >= 1) { a_opacity.finish(); + _a_appearance.stop(); if (_hiding) { - _a_appearance.stop(); deleteLater(); - } else if (dtPos >= 1) { - _a_appearance.stop(); } } else { - a_opacity.update(dtAlpha, a_func); + a_opacity.update(dt, a_func); } setWindowOpacity(a_opacity.current()); - if (dtPos >= 1) { - a_y.finish(); + update(); +} + +void Widget::step_movement(float64 ms, bool timer) { + float64 dt = ms / float64(st::notifyFastAnim); + if (dt >= 1) { + a_top.finish(); + a_bottom.finish(); } else { - a_y.update(dtPos, anim::linear); + a_top.update(dt, anim::linear); + a_bottom.update(dt, anim::linear); } - move(x(), a_y.current()); + setGeometry(x(), a_top.current(), width(), a_bottom.current() - a_top.current()); update(); } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index bb1fd8789..2d2c1cfa5 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -22,6 +22,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "window/notifications_manager.h" +namespace Ui { +class IconButton; +} // namespace Ui + namespace Window { namespace Notifications { namespace Default { @@ -88,22 +92,20 @@ class Widget : public TWidget { public: Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, int x, int y); - void step_appearance(float64 ms, bool timer); - void animHide(float64 duration, anim::transition func); void startHiding(); void stopHiding(); - void moveTo(int x, int y, int index = -1); + void moveTop(int top, int bottom); void updateNotifyDisplay(); void updatePeerPhoto(); void itemRemoved(HistoryItem *del); - int index() const { - return _history ? _index : -1; + int isUnlinked() const { + return !_history; } - void unlinkHistory(History *hist = 0); + void unlinkHistory(History *history = nullptr); ~Widget(); @@ -116,9 +118,20 @@ protected: private slots: void hideByTimer(); void checkLastInput(); + void onReplyResize(); + void onReplySubmit(bool ctrlShiftEnter); + void onReplyCancel(); private: + void animHide(float64 duration, anim::transition func); + void step_appearance(float64 ms, bool timer); + void step_movement(float64 ms, bool timer); void unlinkHistoryAndNotify(); + void toggleActionButtons(bool visible); + void prepareActionsCache(); + void actionsOpacityCallback(); + void showReplyField(); + void sendReply(); #if defined Q_OS_WIN && !defined Q_OS_WINRT uint64 _started; @@ -129,17 +142,27 @@ private: PeerData *_author; HistoryItem *_item; int _forwardedCount; - IconedButton _close; + ChildWidget _close; + ChildWidget _reply; + ChildWidget _replyArea = { nullptr }; + ChildWidget _replySend = { nullptr }; QPixmap _cache; - float64 _alphaDuration, _posDuration; + float64 _alphaDuration; QTimer _hideTimer, _inputTimer; bool _hiding = false; - int _index = 0; + + anim::ivalue a_top, a_bottom; + Animation _a_movement; + anim::fvalue a_opacity; anim::transition a_func; - anim::ivalue a_y; Animation _a_appearance; + int _replyPadding = 0; + bool _actionsVisible = false; + FloatAnimation a_actionsOpacity; + QPixmap _buttonsCache; + ImagePtr peerPhoto; }; diff --git a/Telegram/SourceFiles/window/notifications_utilities.cpp b/Telegram/SourceFiles/window/notifications_utilities.cpp index db2aae815..2d48cdd4c 100644 --- a/Telegram/SourceFiles/window/notifications_utilities.cpp +++ b/Telegram/SourceFiles/window/notifications_utilities.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "pspecific.h" #include "mainwindow.h" +#include "styles/style_window.h" namespace Window { namespace Notifications { diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style new file mode 100644 index 000000000..2c8e3da71 --- /dev/null +++ b/Telegram/SourceFiles/window/window.style @@ -0,0 +1,69 @@ +/* +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); +notifyWaitShortHide: 0; +notifyWaitLongHide: 20000; +notifyFastAnim: 150; +notifyMinWidth: 316px; +notifyMinHeight: 80px; +notifyDeltaX: 6px; +notifyDeltaY: 7px; +notifyActionsDuration: 200; + +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/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index cb4b63355..7598ad52c 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -40,6 +40,7 @@ '<(src_loc)/settings/settings.style', '<(src_loc)/stickers/stickers.style', '<(src_loc)/ui/widgets/widgets.style', + '<(src_loc)/window/window.style', ], 'langpacks': [ 'en', @@ -512,6 +513,8 @@ '<(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', From 41dc0f4e98d6bbaa2ba33135dfabc1888a455ce4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 5 Oct 2016 19:56:27 +0300 Subject: [PATCH 22/32] Hide all button added to default notifications. --- Telegram/Resources/langs/lang.strings | 4 +- Telegram/SourceFiles/apiwrap.h | 2 + Telegram/SourceFiles/application.h | 1 + Telegram/SourceFiles/boxes/contactsbox.h | 1 + Telegram/SourceFiles/boxes/sessionsbox.h | 1 + Telegram/SourceFiles/config.h | 3 - Telegram/SourceFiles/core/lambda_wrap.h | 192 +---- Telegram/SourceFiles/core/single_timer.cpp | 80 +++ Telegram/SourceFiles/core/single_timer.h | 50 ++ Telegram/SourceFiles/core/utils.cpp | 30 - Telegram/SourceFiles/core/utils.h | 31 - Telegram/SourceFiles/history/history_item.cpp | 9 +- Telegram/SourceFiles/historywidget.h | 1 + Telegram/SourceFiles/mainwidget.h | 1 + Telegram/SourceFiles/mainwindow.h | 9 +- Telegram/SourceFiles/mtproto/connection.h | 1 + Telegram/SourceFiles/mtproto/dcenter.h | 11 +- Telegram/SourceFiles/mtproto/facade.h | 5 +- Telegram/SourceFiles/mtproto/rpc_sender.h | 187 ++++- Telegram/SourceFiles/mtproto/session.h | 9 +- .../platform/mac/main_window_mac.mm | 2 +- Telegram/SourceFiles/ui/animation.h | 93 ++- Telegram/SourceFiles/ui/flatinput.cpp | 2 +- Telegram/SourceFiles/ui/toast/toast_manager.h | 1 + .../window/notifications_manager_default.cpp | 677 ++++++++++++------ .../window/notifications_manager_default.h | 200 ++++-- .../window/notifications_utilities.h | 1 + Telegram/SourceFiles/window/window.style | 6 +- Telegram/gyp/Telegram.gyp | 2 + 29 files changed, 1021 insertions(+), 591 deletions(-) create mode 100644 Telegram/SourceFiles/core/single_timer.cpp create mode 100644 Telegram/SourceFiles/core/single_timer.h diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b1e8b1ff7..15295e8b5 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -249,6 +249,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "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_settings_section_general" = "General"; "lng_settings_change_lang" = "Change language"; @@ -872,8 +874,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "lng_send_image_too_large" = "Could not send a file, because it is larger than 1.5 GB :("; "lng_send_folder" = "Could not send «{name}» because it is a directory :("; -"lng_notification_reply" = "Reply"; - "lng_forward_choose" = "Choose recipient..."; "lng_forward_cant" = "Sorry, no way to forward here :("; "lng_forward_confirm" = "Forward to {recipient}?"; diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 524f195c6..23e453bee 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/application.h b/Telegram/SourceFiles/application.h index 60c2d520b..27347b980 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/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 1d3976e6d..646421224 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/sessionsbox.h b/Telegram/SourceFiles/boxes/sessionsbox.h index 51f84d021..851bfa8fb 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/config.h b/Telegram/SourceFiles/config.h index 6a0d52540..85eb99476 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 diff --git a/Telegram/SourceFiles/core/lambda_wrap.h b/Telegram/SourceFiles/core/lambda_wrap.h index b8c6c8e53..22e1ed438 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/single_timer.cpp b/Telegram/SourceFiles/core/single_timer.cpp new file mode 100644 index 000000000..7507a8f14 --- /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 000000000..3aa89647a --- /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 4ad8140ab..63959c272 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 df4c23af3..7fb79b1c0 100644 --- a/Telegram/SourceFiles/core/utils.h +++ b/Telegram/SourceFiles/core/utils.h @@ -172,37 +172,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: diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 15c856248..f792eafd6 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) @@ -629,7 +636,7 @@ void HistoryItem::recountAttachToPrevious() { && !previos->serviceMsg() && !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/historywidget.h b/Telegram/SourceFiles/historywidget.h index cf6c62bca..af7d4e4d5 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -26,6 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "history/history_common.h" #include "history/field_autocomplete.h" #include "window/section_widget.h" +#include "core/single_timer.h" namespace InlineBots { namespace Layout { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index a6d3547ee..9b4027b1a 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; diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index 9ace9c51d..7df6e021e 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "pspecific.h" #include "ui/effects/rect_shadow.h" #include "platform/platform_main_window.h" +#include "core/single_timer.h" class MediaView; class TitleWidget; @@ -41,14 +42,6 @@ namespace Settings { class Widget; } // namespace Settings -namespace Window { -namespace Notifications { -namespace Default { -class Widget; -} // namespace Default -} // namespace Notifications -} // namespace Window - class ConnectingWidget : public QWidget { Q_OBJECT diff --git a/Telegram/SourceFiles/mtproto/connection.h b/Telegram/SourceFiles/mtproto/connection.h index 89c62fb4b..ab2101085 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/dcenter.h b/Telegram/SourceFiles/mtproto/dcenter.h index 4f47c63d3..058ab61fd 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 94f5e39c0..568ecb5b7 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/rpc_sender.h b/Telegram/SourceFiles/mtproto/rpc_sender.h index fb5fd95eb..76839e5a1 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/session.h b/Telegram/SourceFiles/mtproto/session.h index f46694e3a..4c8b17c69 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/platform/mac/main_window_mac.mm b/Telegram/SourceFiles/platform/mac/main_window_mac.mm index ddf50c906..6dd1d6edb 100644 --- a/Telegram/SourceFiles/platform/mac/main_window_mac.mm +++ b/Telegram/SourceFiles/platform/mac/main_window_mac.mm @@ -39,7 +39,7 @@ namespace Platform { void MacPrivate::activeSpaceChanged() { if (auto manager = Window::Notifications::Default::manager()) { - manager->enumerateWidgets([](QWidget *widget) { + manager->enumerateNotifications([](QWidget *widget) { objc_activateWnd(widget->winId()); }); } diff --git a/Telegram/SourceFiles/ui/animation.h b/Telegram/SourceFiles/ui/animation.h index 6842c55a7..eaa496fb8 100644 --- a/Telegram/SourceFiles/ui/animation.h +++ b/Telegram/SourceFiles/ui/animation.h @@ -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.; }; diff --git a/Telegram/SourceFiles/ui/flatinput.cpp b/Telegram/SourceFiles/ui/flatinput.cpp index 6385060a2..de441e418 100644 --- a/Telegram/SourceFiles/ui/flatinput.cpp +++ b/Telegram/SourceFiles/ui/flatinput.cpp @@ -735,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/toast/toast_manager.h b/Telegram/SourceFiles/ui/toast/toast_manager.h index 28419cf72..e8e42f9f8 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/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index f0b57d975..e63719950 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -49,6 +49,10 @@ int notificationWidth() { return result; } +int notificationMaxHeight() { + return st::notifyMinHeight + st::notifyReplyArea.heightMax + st::notifyBorderWidth; +} + } // namespace void start() { @@ -65,69 +69,173 @@ void finish() { Manager::Manager() { subscribe(FileDownload::ImageLoaded(), [this] { - for_const (auto widget, _widgets) { - widget->updatePeerPhoto(); + for_const (auto notification, _notifications) { + notification->updatePeerPhoto(); } }); + _inputCheckTimer.setTimeoutHandler([this] { checkLastInput(); }); +} + +void Manager::checkLastInput() { + auto waiting = false; + for_const (auto notification, _notifications) { + if (!notification->checkLastInput()) { + waiting = true; + } + } + if (waiting) { + _inputCheckTimer.start(300); + } } void Manager::startAllHiding() { - for_const (auto widget, _widgets) { - widget->startHiding(); + auto hasReplyingNotification = false; + for_const (auto notification, _notifications) { + if (notification->isReplying()) { + hasReplyingNotification = true; + break; + } + } + 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 widget, _widgets) { - widget->stopHiding(); + for_const (auto notification, _notifications) { + notification->stopHiding(); + } + if (_hideAll) { + _hideAll->stopHiding(); } } void Manager::showNextFromQueue() { - if (_queuedNotifications.isEmpty()) { - return; + if (!_queuedNotifications.isEmpty()) { + int count = kNotifyWindowsCount; + for_const (auto notification, _notifications) { + if (notification->isUnlinked()) continue; + --count; + } + if (count > 0) { + auto position = notificationStartPosition(); + do { + auto queued = _queuedNotifications.front(); + _queuedNotifications.pop_front(); + + auto notification = std_::make_unique( + queued.history, + queued.peer, + queued.author, + queued.item, + queued.forwardedCount, + position); + Platform::Notifications::defaultNotificationShown(notification.get()); + _notifications.push_back(notification.release()); + --count; + } while (count > 0 && !_queuedNotifications.isEmpty()); + + _positionsOutdated = true; + checkLastInput(); + } } - - int count = kNotifyWindowsCount; - for_const (auto widget, _widgets) { - if (widget->isUnlinked()) continue; - --count; - } - if (count <= 0) { - return; - } - - auto r = psDesktopRect(); - auto x = r.x() + r.width() - notificationWidth() - st::notifyDeltaX; - auto y = r.y() + r.height(); - do { - auto queued = _queuedNotifications.front(); - _queuedNotifications.pop_front(); - - auto widget = std_::make_unique(queued.history, queued.peer, queued.author, queued.item, queued.forwardedCount, x, y); - Platform::Notifications::defaultNotificationShown(widget.get()); - _widgets.push_back(widget.release()); - --count; - } while (count > 0 && !_queuedNotifications.isEmpty()); - - auto bottom = y - st::notifyDeltaY; - for_const (auto widget, _widgets) { - if (widget->isUnlinked() < 0) continue; - widget->moveTop(y - widget->height(), y); - y -= widget->height() + st::notifyDeltaY; + if (_positionsOutdated) { + moveWidgets(); } } -void Manager::removeFromShown(Widget *remove) { +QPoint Manager::notificationStartPosition() const { + auto r = psDesktopRect(); + auto x = r.x() + r.width() - notificationWidth() - st::notifyDeltaX; + auto y = r.y() + r.height(); + return QPoint(x, y); +} + +void Manager::moveWidgets() { + auto startPosition = notificationStartPosition(); + auto top = startPosition.y(); + int firstLeft = 0, firstTopCurrent = 0, firstTop = 0, count = 0; + for (int i = _notifications.size(); i != 0;) { + auto notification = _notifications[--i]; + if (notification->isUnlinked()) continue; + + top -= notification->height() + st::notifyDeltaY; + notification->moveTop(top); + + firstLeft = notification->x(); + firstTopCurrent = notification->y(); + firstTop = top; + + ++count; + } + + if (count > 1 || !_queuedNotifications.isEmpty()) { + auto deltaY = st::notifyHideAll.height + st::notifyDeltaY; + if (!_hideAll) { + _hideAll = new HideAllButton(QPoint(firstLeft, firstTopCurrent - deltaY)); + } + _hideAll->moveTop(firstTop - deltaY); + _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, Notification::AddToHeight::Above); + auto index = _notifications.indexOf(notification); + if (index > 0) { + for (int i = 0; i != index; ++i) { + auto notification = _notifications[i]; + if (notification->isUnlinked()) continue; + + notification->addToTop(-deltaHeight); + } + } + if (_hideAll) { + _hideAll->addToTop(-deltaHeight); + } +} + +void Manager::unlinkFromShown(Notification *remove) { if (remove) { - auto index = _widgets.indexOf(remove); - if (index >= 0) { - _widgets.removeAt(index); + 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(); @@ -135,18 +243,19 @@ void Manager::doShowNotification(HistoryItem *item, int forwardedCount) { void Manager::doClearAll() { _queuedNotifications.clear(); - for_const (auto widget, _widgets) { - widget->unlinkHistory(); + for_const (auto notification, _notifications) { + notification->unlinkHistory(); } + showNextFromQueue(); } void Manager::doClearAllFast() { _queuedNotifications.clear(); - - auto widgets = createAndSwap(_widgets); - for_const (auto widget, widgets) { - widget->deleteLater(); + auto notifications = createAndSwap(_notifications); + for_const (auto notification, notifications) { + notification->deleteLater(); } + showNextFromQueue(); } void Manager::doClearFromHistory(History *history) { @@ -157,21 +266,24 @@ void Manager::doClearFromHistory(History *history) { ++i; } } - for_const (auto widget, _widgets) { - widget->unlinkHistory(history); + for_const (auto notification, _notifications) { + if (notification->unlinkHistory(history)) { + _positionsOutdated = true; + } } showNextFromQueue(); } void Manager::doClearFromItem(HistoryItem *item) { - for_const (auto widget, _widgets) { - widget->itemRemoved(item); + for_const (auto notification, _notifications) { + // Calls unlinkFromShown() -> showNextFromQueue() + notification->itemRemoved(item); } } void Manager::doUpdateAll() { - for_const (auto widget, _widgets) { - widget->updateNotifyDisplay(); + for_const (auto notification, _notifications) { + notification->updateNotifyDisplay(); } } @@ -179,7 +291,116 @@ Manager::~Manager() { clearAllFast(); } -Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *msg, int forwardedCount, int x, int y) : TWidget(nullptr) +namespace internal { + +Widget::Widget(QPoint position) : TWidget(nullptr) +, _opacityDuration(st::notifyFastAnim) +, a_opacity(0, 1) +, a_func(anim::linear) +, _a_appearance(animation(this, &Widget::step_appearance)) +, a_top(position.y()) +, _a_movement(animation(this, &Notification::step_movement)) { + setWindowOpacity(0.); + + setAttribute(Qt::WA_OpaquePaintEvent); + + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint); + setAttribute(Qt::WA_MacAlwaysShowToolWindow); + setAttribute(Qt::WA_NoSystemBackground, true); + setAttribute(Qt::WA_TranslucentBackground, true); + + _a_appearance.start(); +} + +void Widget::step_appearance(float64 ms, bool timer) { + float64 dt = ms / float64(_opacityDuration); + if (dt >= 1) { + a_opacity.finish(); + _a_appearance.stop(); + if (_hiding) { + deleteLater(); + } + } else { + a_opacity.update(dt, a_func); + } + setWindowOpacity(a_opacity.current()); + update(); +} + +void Widget::step_movement(float64 ms, bool timer) { + float64 dt = ms / float64(st::notifyFastAnim); + if (dt >= 1) { + a_top.finish(); + } else { + a_top.update(dt, anim::linear); + } + move(x(), a_top.current()); + update(); +} + +void Widget::hideSlow() { + animHide(st::notifySlowHide, st::notifySlowHideFunc); +} + +void Widget::hideFast() { + animHide(st::notifyFastAnim, anim::linear); +} + +void Widget::hideStop() { + if (_hiding) { + _opacityDuration = st::notifyFastAnim; + a_func = anim::linear; + a_opacity.start(1); + _hiding = false; + _a_appearance.start(); + } +} + +void Widget::animHide(float64 duration, anim::transition func) { + _opacityDuration = duration; + a_func = func; + a_opacity.start(0); + _hiding = true; + _a_appearance.start(); +} + +void Widget::moveTop(int top) { + a_top.start(top); + _a_movement.start(); +} + +void Widget::addToHeight(int add, AddToHeight aboveOrBelow) { + int newHeight = height() + add; + if (aboveOrBelow == AddToHeight::Above) { + a_top.add(-add); + } + updateGeometry(x(), a_top.current(), width(), newHeight); +} + +void Widget::updateGeometry(int x, int y, int width, int height) { + setGeometry(x, y, width, height); + update(); +} + +void Widget::addToTop(int add) { + a_top.add(add); + move(x(), a_top.current()); +} + +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 position) : Widget(position) , _history(history) , _peer(peer) , _author(author) @@ -189,26 +410,17 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem * , _started(GetTickCount()) #endif // Q_OS_WIN && !Q_OS_WINRT , _close(this, st::notifyClose) -, _reply(this, lang(lng_notification_reply), st::defaultBoxButton) -, _alphaDuration(st::notifyFastAnim) -, a_opacity(0) -, a_func(anim::linear) -, a_top(y) -, a_bottom(y + st::notifyMinHeight) -, _a_movement(animation(this, &Widget::step_movement)) -, _a_appearance(animation(this, &Widget::step_appearance)) { - setGeometry(x, a_top.current(), notificationWidth(), a_bottom.current() - a_top.current()); +, _reply(this, lang(lng_notification_reply), st::defaultBoxButton) { + updateGeometry(position.x(), position.y(), notificationWidth(), st::notifyMinHeight); + _userpicLoaded = _peer ? _peer->userpicLoaded() : true; updateNotifyDisplay(); _hideTimer.setSingleShot(true); - connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideByTimer())); - - _inputTimer.setSingleShot(true); - connect(&_inputTimer, SIGNAL(timeout()), this, SLOT(checkLastInput())); + connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(onHideByTimer())); _close->setClickedCallback([this] { - unlinkHistoryAndNotify(); + unlinkHistoryInManager(); }); _close->setAcceptBoth(true); _close->moveToRight(st::notifyClosePos.x(), st::notifyClosePos.y()); @@ -223,21 +435,15 @@ Widget::Widget(History *history, PeerData *peer, PeerData *author, HistoryItem * prepareActionsCache(); - a_opacity.start(1); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint); setAttribute(Qt::WA_MacAlwaysShowToolWindow); + setAttribute(Qt::WA_NoSystemBackground, true); + setAttribute(Qt::WA_TranslucentBackground, true); show(); - - setWindowOpacity(a_opacity.current()); - - _alphaDuration = st::notifyFastAnim; - _a_appearance.start(); - - checkLastInput(); } -void Widget::prepareActionsCache() { +void Notification::prepareActionsCache() { auto replyCache = myGrab(_reply); auto fadeWidth = st::notifyFadeRight.width(); auto actionsTop = st::notifyTextTop + st::msgNameFont->height; @@ -254,53 +460,73 @@ void Widget::prepareActionsCache() { _buttonsCache = App::pixmapFromImageInPlace(std_::move(actionsCacheImg)); } -void Widget::checkLastInput() { +bool Notification::checkLastInput() { + 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); - if (!res || lii.dwTime >= _started) { - _hideTimer.start(st::notifyWaitLongHide); - } else { - _inputTimer.start(300); + wasUserInput = (!res || lii.dwTime >= _started); +#endif // Q_OS_WIN && !Q_OS_WINRT + if (wasUserInput) { + _waitingForInput = false; + if (!isReplying()) { + _hideTimer.start(st::notifyWaitLongHide); + } + return true; } -#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 + return false; } -void Widget::onReplyResize() { - _a_movement.stop(); - auto newHeight = st::notifyMinHeight + _replyArea->height() + st::notifyBorderWidth; - auto delta = height() - newHeight; - if (delta != 0) { - auto top = a_top.current() + delta; - a_top = anim::ivalue(top, top); - setGeometry(x(), top, width(), a_bottom.current() - top); - update(); - } +void Notification::onReplyResize() { + changeHeight(st::notifyMinHeight + _replyArea->height() + st::notifyBorderWidth); } -void Widget::onReplySubmit(bool ctrlShiftEnter) { +void Notification::onReplySubmit(bool ctrlShiftEnter) { sendReply(); } -void Widget::onReplyCancel() { - unlinkHistoryAndNotify(); +void Notification::onReplyCancel() { + unlinkHistoryInManager(); } -void Widget::moveTop(int top, int bottom) { - a_top.start(top); - a_bottom.start(bottom); - _a_movement.start(); +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 Widget::updateNotifyDisplay() { +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; int32 w = width(), h = height(); @@ -372,50 +598,48 @@ void Widget::updateNotifyDisplay() { update(); } -void Widget::updatePeerPhoto() { - if (!peerPhoto->isNull() && peerPhoto->loaded()) { - auto img = _cache.toImage(); - { - Painter p(&img); - p.drawPixmap(st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), peerPhoto->pix(st::notifyPhotoSize)); - } - peerPhoto = ImagePtr(); - _cache = App::pixmapFromImageInPlace(std_::move(img)); - 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)); } -void Widget::itemRemoved(HistoryItem *deleted) { +void Notification::itemRemoved(HistoryItem *deleted) { if (_item && _item == deleted) { _item = nullptr; - unlinkHistoryAndNotify(); + unlinkHistoryInManager(); } } -void Widget::unlinkHistoryAndNotify() { - unlinkHistory(); +void Notification::unlinkHistoryInManager() { if (auto manager = ManagerInstance.data()) { - manager->showNextFromQueue(); + manager->unlinkFromShown(this); } } -void Widget::toggleActionButtons(bool visible) { +void Notification::toggleActionButtons(bool visible) { if (_actionsVisible != visible) { _actionsVisible = visible; - _reply->hide(); a_actionsOpacity.start([this] { actionsOpacityCallback(); }, _actionsVisible ? 0. : 1., _actionsVisible ? 1. : 0., st::notifyActionsDuration); + _reply->hide(); } } -void Widget::actionsOpacityCallback() { - update(); - if (!a_actionsOpacity.animating() && _actionsVisible) { - _reply->show(); - } -} - -void Widget::showReplyField() { +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); @@ -435,37 +659,42 @@ void Widget::showReplyField() { toggleActionButtons(false); - a_top.finish(); - a_bottom.finish(); - - _a_movement.stop(); - auto top = a_top.current() - _replyArea->height() - st::notifyBorderWidth; - auto bottom = a_top.current() + st::notifyMinHeight; - a_top = anim::ivalue(top, top); - a_bottom = anim::ivalue(bottom, bottom); - setGeometry(x(), top, width(), bottom - top); + onReplyResize(); update(); } -void Widget::sendReply() { +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 Widget::unlinkHistory(History *history) { - if (!history || history == _history) { - animHide(st::notifyFastAnim, anim::linear); +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) { + if (_history->peer->id != 4456802837) { + int a = 0; + } + hideFast(); _history = nullptr; _item = nullptr; } + return unlink; } -void Widget::enterEvent(QEvent *e) { +void Notification::enterEvent(QEvent *e) { if (!_history) return; if (auto manager = ManagerInstance.data()) { manager->stopAllHiding(); @@ -475,7 +704,7 @@ void Widget::enterEvent(QEvent *e) { } } -void Widget::leaveEvent(QEvent *e) { +void Notification::leaveEvent(QEvent *e) { if (!_history) return; if (auto manager = ManagerInstance.data()) { manager->startAllHiding(); @@ -483,15 +712,16 @@ void Widget::leaveEvent(QEvent *e) { toggleActionButtons(false); } -void Widget::startHiding() { - _hideTimer.start(st::notifyWaitShortHide); +void Notification::startHiding() { + if (!_history) return; + hideSlow(); } -void Widget::mousePressEvent(QMouseEvent *e) { +void Notification::mousePressEvent(QMouseEvent *e) { if (!_history) return; if (e->button() == Qt::RightButton) { - unlinkHistoryAndNotify(); + unlinkHistoryInManager(); } else { e->ignore(); if (auto manager = ManagerInstance.data()) { @@ -502,88 +732,89 @@ void Widget::mousePressEvent(QMouseEvent *e) { } } -void Widget::paintEvent(QPaintEvent *e) { - Painter p(this); - 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); - } - - if (height() > st::notifyMinHeight) { - auto replyAreaHeight = height() - st::notifyMinHeight - st::notifyBorderWidth; - if (replyAreaHeight > 0) { - p.fillRect(st::notifyBorderWidth, st::notifyMinHeight, width() - 2 * st::notifyBorderWidth, replyAreaHeight, st::notifyBg); - } - p.fillRect(0, st::notifyMinHeight, st::notifyBorderWidth, height() - st::notifyMinHeight, st::notifyBorder); - p.fillRect(width() - st::notifyBorderWidth, st::notifyMinHeight, st::notifyBorderWidth, height() - st::notifyMinHeight, st::notifyBorder); - p.fillRect(st::notifyBorderWidth, height() - st::notifyBorderWidth, width() - 2 * st::notifyBorderWidth, st::notifyBorderWidth, st::notifyBorder); - } -} - -void Widget::animHide(float64 duration, anim::transition func) { +void Notification::stopHiding() { if (!_history) return; - _alphaDuration = duration; - a_func = func; - a_opacity.start(0); - _hiding = true; - _a_appearance.start(); -} - -void Widget::stopHiding() { - if (!_history) return; - _alphaDuration = st::notifyFastAnim; - a_func = anim::linear; - a_opacity.start(1); - _hiding = false; _hideTimer.stop(); - _a_appearance.start(); + Widget::hideStop(); } -void Widget::hideByTimer() { - if (!_history) return; - animHide(st::notifySlowHide, st::notifySlowHideFunc); +void Notification::onHideByTimer() { + startHiding(); } -void Widget::step_appearance(float64 ms, bool timer) { - float64 dt = ms / float64(_alphaDuration); - if (dt >= 1) { - a_opacity.finish(); - _a_appearance.stop(); - if (_hiding) { - deleteLater(); - } - } else { - a_opacity.update(dt, a_func); - } - setWindowOpacity(a_opacity.current()); - update(); -} - -void Widget::step_movement(float64 ms, bool timer) { - float64 dt = ms / float64(st::notifyFastAnim); - if (dt >= 1) { - a_top.finish(); - a_bottom.finish(); - } else { - a_top.update(dt, anim::linear); - a_bottom.update(dt, anim::linear); - } - setGeometry(x(), a_top.current(), width(), a_bottom.current() - a_top.current()); - update(); -} - -Widget::~Widget() { +Notification::~Notification() { if (auto manager = ManagerInstance.data()) { manager->removeFromShown(this); } } +HideAllButton::HideAllButton(QPoint position) : Widget(position) { + setCursor(style::cur_pointer); + + updateGeometry(position.x(), position.y(), notificationWidth(), 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 = createAndSwap(_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 index 2d2c1cfa5..6094b8037 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -21,6 +21,7 @@ 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; @@ -29,9 +30,12 @@ class IconButton; namespace Window { namespace Notifications { namespace Default { +namespace internal { +class Notification; +class HideAllButton; +} // namespace internal class Manager; -class Widget; void start(); Manager *manager(); @@ -41,21 +45,21 @@ class Manager : public Notifications::Manager, private base::Subscriber { public: Manager(); - void showNextFromQueue(); - void removeFromShown(Widget *remove); - void startAllHiding(); - void stopAllHiding(); - template - void enumerateWidgets(Method method) { - for_const (auto widget, _widgets) { - method(widget); + void enumerateNotifications(Method method) { + for_const (auto notification, _notifications) { + method(notification); } } ~Manager(); private: + using Notification = internal::Notification; + friend class Notification; + using HideAllButton = internal::HideAllButton; + friend class HideAllButton; + void doUpdateAll() override; void doShowNotification(HistoryItem *item, int forwardedCount) override; void doClearAll() override; @@ -63,8 +67,25 @@ private: void doClearFromHistory(History *history) override; void doClearFromItem(HistoryItem *item) override; - using Widgets = QList; - Widgets _widgets; + void showNextFromQueue(); + void unlinkFromShown(Notification *remove); + void removeFromShown(Notification *remove); + void removeHideAll(HideAllButton *remove); + void startAllHiding(); + void stopAllHiding(); + void checkLastInput(); + + QPoint notificationStartPosition() const; + void moveWidgets(); + void changeNotificationHeight(Notification *widget, int newHeight); + + using Notifications = QList; + Notifications _notifications; + + HideAllButton *_hideAll = nullptr; + + bool _positionsOutdated = false; + SingleTimer _inputCheckTimer; struct QueuedNotification { QueuedNotification(HistoryItem *item, int forwardedCount) @@ -86,52 +107,109 @@ private: }; +namespace internal { + class Widget : public TWidget { - Q_OBJECT - public: - Widget(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, int x, int y); + Widget(QPoint position); - void startHiding(); - void stopHiding(); - void moveTop(int top, int bottom); - - void updateNotifyDisplay(); - void updatePeerPhoto(); - - void itemRemoved(HistoryItem *del); - - int isUnlinked() const { - return !_history; + bool isShowing() const { + return _a_appearance.animating() && !_hiding; } + void moveTop(int top); - void unlinkHistory(History *history = nullptr); - - ~Widget(); + enum class AddToHeight { + Above, + Below, + }; + void addToHeight(int add, AddToHeight aboveOrBelow); + void addToTop(int add); protected: - void enterEvent(QEvent *e) override; - void leaveEvent(QEvent *e) override; - void mousePressEvent(QMouseEvent *e) override; - void paintEvent(QPaintEvent *e) override; + void hideSlow(); + void hideFast(); + void hideStop(); -private slots: - void hideByTimer(); - void checkLastInput(); - void onReplyResize(); - void onReplySubmit(bool ctrlShiftEnter); - void onReplyCancel(); + virtual void updateGeometry(int x, int y, int width, int height); private: void animHide(float64 duration, anim::transition func); void step_appearance(float64 ms, bool timer); void step_movement(float64 ms, bool timer); - void unlinkHistoryAndNotify(); + + bool _hiding = false; + float64 _opacityDuration; + anim::fvalue a_opacity; + anim::transition a_func; + Animation _a_appearance; + + anim::ivalue a_top; + Animation _a_movement; + +}; + +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 position); + + 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(); + + ~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: + void unlinkHistoryInManager(); void toggleActionButtons(bool visible); void prepareActionsCache(); - void actionsOpacityCallback(); void showReplyField(); void sendReply(); + void changeHeight(int newHeight); + void updateGeometry(int x, int y, int width, int height) override; + void actionsOpacityCallback(); + + QPixmap _cache; + + bool _actionsVisible = false; + FloatAnimation a_actionsOpacity; + QPixmap _buttonsCache; #if defined Q_OS_WIN && !defined Q_OS_WINRT uint64 _started; @@ -144,29 +222,43 @@ private: int _forwardedCount; ChildWidget _close; ChildWidget _reply; + ChildWidget _background = { nullptr }; ChildWidget _replyArea = { nullptr }; ChildWidget _replySend = { nullptr }; - QPixmap _cache; - float64 _alphaDuration; - QTimer _hideTimer, _inputTimer; - bool _hiding = false; + bool _waitingForInput = true; - anim::ivalue a_top, a_bottom; - Animation _a_movement; - - anim::fvalue a_opacity; - anim::transition a_func; - Animation _a_appearance; + QTimer _hideTimer; int _replyPadding = 0; - bool _actionsVisible = false; - FloatAnimation a_actionsOpacity; - QPixmap _buttonsCache; - ImagePtr peerPhoto; + bool _userpicLoaded = false; }; +class HideAllButton : public Widget { +public: + HideAllButton(QPoint position); + + 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.h b/Telegram/SourceFiles/window/notifications_utilities.h index 384690d30..f5609210b 100644 --- a/Telegram/SourceFiles/window/notifications_utilities.h +++ b/Telegram/SourceFiles/window/notifications_utilities.h @@ -21,6 +21,7 @@ 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 { diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index 2c8e3da71..c2b4a20d2 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -35,8 +35,7 @@ notifyItemTop: 12px; notifyTextLeft: 12px; notifyTextTop: 7px; notifySlowHideFunc: transition(easeInCirc); -notifyWaitShortHide: 0; -notifyWaitLongHide: 20000; +notifyWaitLongHide: 3000; notifyFastAnim: 150; notifyMinWidth: 316px; notifyMinHeight: 80px; @@ -44,6 +43,9 @@ notifyDeltaX: 6px; notifyDeltaY: 7px; notifyActionsDuration: 200; +notifyHideAll: RoundButton(defaultBoxButton) { +} + notifyFadeRight: icon {{ "fade_horizontal_right", notifyBg }}; notifyReplyArea: InputArea(defaultInputArea) { font: normalFont; diff --git a/Telegram/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 7598ad52c..8f096ee36 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -205,6 +205,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', From e7b6d7b49845bb2b7dcad9b36820b129a5336b84 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 5 Oct 2016 21:37:48 +0300 Subject: [PATCH 23/32] Advanced notifications settings box layout done. --- Telegram/Resources/icons/monitor.png | Bin 0 -> 3962 bytes Telegram/Resources/icons/monitor@2x.png | Bin 0 -> 10782 bytes Telegram/Resources/langs/lang.strings | 3 + Telegram/SourceFiles/boxes/boxes.style | 9 + .../SourceFiles/boxes/notifications_box.cpp | 108 ++++++++++++ .../SourceFiles/boxes/notifications_box.h | 52 ++++++ Telegram/SourceFiles/settings/settings.style | 11 -- .../settings_notifications_widget.cpp | 15 ++ .../settings/settings_notifications_widget.h | 2 + .../settings/settings_scale_widget.cpp | 134 +-------------- .../settings/settings_scale_widget.h | 53 +----- .../ui/widgets/discrete_slider.cpp | 161 ++++++++++++++++++ .../SourceFiles/ui/widgets/discrete_slider.h | 72 ++++++++ Telegram/SourceFiles/ui/widgets/widgets.style | 11 ++ Telegram/gyp/Telegram.gyp | 4 + 15 files changed, 443 insertions(+), 192 deletions(-) create mode 100644 Telegram/Resources/icons/monitor.png create mode 100644 Telegram/Resources/icons/monitor@2x.png create mode 100644 Telegram/SourceFiles/boxes/notifications_box.cpp create mode 100644 Telegram/SourceFiles/boxes/notifications_box.h create mode 100644 Telegram/SourceFiles/ui/widgets/discrete_slider.cpp create mode 100644 Telegram/SourceFiles/ui/widgets/discrete_slider.h diff --git a/Telegram/Resources/icons/monitor.png b/Telegram/Resources/icons/monitor.png new file mode 100644 index 0000000000000000000000000000000000000000..b1829c2b790ff36e8c9d4b2c7b18b16ea987c7b2 GIT binary patch literal 3962 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 BQjP!s literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/monitor@2x.png b/Telegram/Resources/icons/monitor@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..42356354f969d761a131de29d1468241ba87f236 GIT binary patch literal 10782 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 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 15295e8b5..c8384625e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -245,6 +245,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "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"; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 61f024f8b..971ea807c 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -89,3 +89,12 @@ 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; diff --git a/Telegram/SourceFiles/boxes/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp new file mode 100644 index 000000000..74909368c --- /dev/null +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -0,0 +1,108 @@ +/* +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" + +namespace { + +constexpr int kMaxNotificationsCount = 5; + +} // namespace + +NotificationsBox::NotificationsBox() : AbstractBox() +, _countSlider(this) +, _save(this, lang(lng_settings_save), st::defaultBoxButton) +, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { + for (int i = 0; i != kMaxNotificationsCount; ++i) { + _countSlider->addSection(QString::number(i + 1)); + } + _countSlider->setActiveSectionFast(2); + + setMouseTracking(true); + _save->setClickedCallback([this] { + + }); + connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose())); + + 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 screenLeft = (width() - st::notificationsBoxScreenSize.width()) / 2; + 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()); + + auto labelTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop; + p.drawTextLeft(contentLeft, labelTop, width(), lang(lng_settings_notifications_count)); +} + +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) { + _save->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save->height()); + _cancel->moveToRight(st::boxButtonPadding.right() + _save->width() + st::boxButtonPadding.left(), _save->y()); + + 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::mousePressEvent(QMouseEvent *e) { + +} + +void NotificationsBox::mouseMoveEvent(QMouseEvent *e) { + +} + +void NotificationsBox::mouseReleaseEvent(QMouseEvent *e) { + +} diff --git a/Telegram/SourceFiles/boxes/notifications_box.h b/Telegram/SourceFiles/boxes/notifications_box.h new file mode 100644 index 000000000..14cc0ab34 --- /dev/null +++ b/Telegram/SourceFiles/boxes/notifications_box.h @@ -0,0 +1,52 @@ +/* +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 { + Q_OBJECT + +public: + NotificationsBox(); + +protected: + void paintEvent(QPaintEvent *e) override; + void resizeEvent(QResizeEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + +private: + QRect getScreenRect() const; + int getContentLeft() const; + + ChildWidget _countSlider; + ChildWidget _save, _cancel; + +}; diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style index bf41030ca..0bb31a9a5 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_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 03370744b..3db9684e1 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -28,6 +28,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "ui/flatcheckbox.h" #include "mainwindow.h" #include "window/notifications_manager.h" +#include "boxes/notifications_box.h" namespace Settings { @@ -74,6 +75,10 @@ void NotificationsWidget::createControls() { 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() { @@ -149,6 +154,16 @@ void NotificationsWidget::onNativeNotifications() { Window::Notifications::manager()->clearAllFast(); Global::SetNativeNotifications(_nativeNotifications->checked()); Local::writeUserSettings(); + + 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 3c68f1c34..dd07c6e3f 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.h +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.h @@ -37,6 +37,7 @@ private slots: void onNativeNotifications(); void onPlaySound(); void onIncludeMuted(); + void onAdvanced(); private: void createControls(); @@ -49,6 +50,7 @@ private: 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 7660e5050..82237a48d 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(); } diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.h b/Telegram/SourceFiles/settings/settings_scale_widget.h index 1a4485c45..d518b253c 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 @@ -89,7 +46,7 @@ private: void setScale(DBIScale newScale); ChildWidget _auto = { nullptr }; - ChildWidget _scale = { nullptr }; + ChildWidget _scale = { nullptr }; }; diff --git a/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp b/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp new file mode 100644 index 000000000..65486067b --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp @@ -0,0 +1,161 @@ +/* +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::setActiveSection(int index) { + setSelectedSection(index); + if (_activeIndex != index) { + _activeIndex = index; + emit sectionActivated(); + } +} + +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 000000000..3235e00ec --- /dev/null +++ b/Telegram/SourceFiles/ui/widgets/discrete_slider.h @@ -0,0 +1,72 @@ +/* +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 { + Q_OBJECT + +public: + DiscreteSlider(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; + +}; + +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/widgets/widgets.style b/Telegram/SourceFiles/ui/widgets/widgets.style index 53f5e17d6..de5690e48 100644 --- a/Telegram/SourceFiles/ui/widgets/widgets.style +++ b/Telegram/SourceFiles/ui/widgets/widgets.style @@ -34,3 +34,14 @@ defaultLabelSimple: LabelSimple { } 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/gyp/Telegram.gyp b/Telegram/gyp/Telegram.gyp index 8f096ee36..79e4169ba 100644 --- a/Telegram/gyp/Telegram.gyp +++ b/Telegram/gyp/Telegram.gyp @@ -176,6 +176,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', @@ -453,6 +455,8 @@ '<(src_loc)/ui/widgets/label_simple.cpp', '<(src_loc)/ui/widgets/label_simple.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/button.cpp', From 16ce28f4d25e43cb8fe2ec519316940080dd2bda Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 6 Oct 2016 19:41:09 +0300 Subject: [PATCH 24/32] Notifications settings done: screen corner selection + max count. --- Telegram/SourceFiles/boxes/boxes.style | 12 + .../SourceFiles/boxes/notifications_box.cpp | 312 +++++++++++++++++- .../SourceFiles/boxes/notifications_box.h | 31 +- Telegram/SourceFiles/facades.cpp | 6 + Telegram/SourceFiles/facades.h | 21 ++ Telegram/SourceFiles/localstorage.cpp | 22 +- .../settings/settings_scale_widget.cpp | 5 +- .../settings/settings_scale_widget.h | 2 +- .../ui/widgets/discrete_slider.cpp | 8 +- .../SourceFiles/ui/widgets/discrete_slider.h | 13 +- .../window/notifications_manager_default.cpp | 237 ++++++++----- .../window/notifications_manager_default.h | 56 ++-- Telegram/SourceFiles/window/window.style | 2 +- 13 files changed, 594 insertions(+), 133 deletions(-) diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 971ea807c..306381f21 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -98,3 +98,15 @@ 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/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp index 74909368c..2e9962411 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.cpp +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -25,6 +25,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #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 { @@ -32,21 +36,83 @@ 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(); + deleteLater(); + } + } + + NotificationsBox *_owner; + QPixmap _cache; + FloatAnimation _opacity; + bool _hiding = false; + +}; + NotificationsBox::NotificationsBox() : AbstractBox() +, _chosenCorner(Global::NotificationsCorner()) +, _oldCount(snap(Global::NotificationsCount(), 1, kMaxNotificationsCount)) , _countSlider(this) -, _save(this, lang(lng_settings_save), st::defaultBoxButton) -, _cancel(this, lang(lng_cancel), st::cancelBoxButton) { +, _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(2); + _countSlider->setActiveSectionFast(_oldCount - 1); + _countSlider->setSectionActivatedCallback([this] { countChanged(); }); setMouseTracking(true); - _save->setClickedCallback([this] { - - }); - connect(_cancel, SIGNAL(clicked()), this, SLOT(onClose())); + _done->setClickedCallback([this] { onClose(); }); + prepareNotificationSampleSmall(); + prepareNotificationSampleLarge(); setMaxHeight(st::notificationsBoxHeight); prepare(); @@ -62,17 +128,55 @@ void NotificationsBox::paintEvent(QPaintEvent *e) { p.setPen(st::boxTitleFg); p.drawTextLeft(contentLeft, st::boxTitlePosition.y(), width(), lang(lng_settings_notifications_position)); - auto screenLeft = (width() - st::notificationsBoxScreenSize.width()) / 2; 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; } @@ -84,8 +188,7 @@ QRect NotificationsBox::getScreenRect() const { } void NotificationsBox::resizeEvent(QResizeEvent *e) { - _save->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _save->height()); - _cancel->moveToRight(st::boxButtonPadding.right() + _save->width() + st::boxButtonPadding.left(), _save->y()); + _done->moveToRight(st::boxButtonPadding.right(), height() - st::boxButtonPadding.bottom() - _done->height()); auto screenRect = getScreenRect(); auto sliderTop = screenRect.y() + screenRect.height() + st::notificationsBoxCountLabelTop + st::notificationsBoxCountTop; @@ -95,14 +198,201 @@ void NotificationsBox::resizeEvent(QResizeEvent *e) { AbstractBox::resizeEvent(e); } -void NotificationsBox::mousePressEvent(QMouseEvent *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::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); + + 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); + + 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); + + 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); + 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); + } + + _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 = createAndSwap(_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 index 14cc0ab34..9e978f4f7 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.h +++ b/Telegram/SourceFiles/boxes/notifications_box.h @@ -30,23 +30,48 @@ class DiscreteSlider; } // namespace Ui class NotificationsBox : public AbstractBox { - Q_OBJECT - 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(); + 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 _save, _cancel; + ChildWidget _done; + + QVector _cornerSamples[4]; }; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 3ebe4eec0..6071638e8 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -635,6 +635,9 @@ struct Data { bool IncludeMuted = true; DBINotifyView NotifyView = dbinvShowPreview; bool NativeNotifications = false; + int NotificationsCount = 3; + Notify::ScreenCorner NotificationsCorner = Notify::ScreenCorner::BottomRight; + bool NotificationsDemoIsShown = false; base::Observable NotifySettingsChanged; DBIConnectionType ConnectionType = dbictAuto; @@ -742,6 +745,9 @@ DefineVar(Global, bool, RestoreSoundNotifyFromTray); DefineVar(Global, bool, IncludeMuted); DefineVar(Global, DBINotifyView, NotifyView); 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 4d2577e52..c0d6c6d15 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -149,8 +149,26 @@ enum class ChangeType { IncludeMuted, DesktopEnabled, ViewParams, + 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(); @@ -308,6 +326,9 @@ DeclareVar(bool, RestoreSoundNotifyFromTray); DeclareVar(bool, IncludeMuted); DeclareVar(DBINotifyView, NotifyView); 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/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index e8c6cc448..9f43d60f4 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -549,6 +549,8 @@ enum { dbiVideoVolume = 0x42, dbiStickersRecentLimit = 0x43, dbiNativeNotifications = 0x44, + dbiNotificationsCount = 0x45, + dbiNotificationsCorner = 0x46, dbiEncryptedWithSalt = 333, dbiEncrypted = 444, @@ -1004,6 +1006,22 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) { 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: { qint32 v; stream >> v; @@ -1572,7 +1590,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)); @@ -1597,6 +1615,8 @@ void _writeUserSettings() { data.stream << quint32(dbiDesktopNotify) << qint32(Global::DesktopNotify()); data.stream << quint32(dbiNotifyView) << qint32(Global::NotifyView()); 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()); diff --git a/Telegram/SourceFiles/settings/settings_scale_widget.cpp b/Telegram/SourceFiles/settings/settings_scale_widget.cpp index 82237a48d..6fb6a3859 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_scale_widget.cpp @@ -59,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() { @@ -102,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 d518b253c..39684d754 100644 --- a/Telegram/SourceFiles/settings/settings_scale_widget.h +++ b/Telegram/SourceFiles/settings/settings_scale_widget.h @@ -38,10 +38,10 @@ public: private slots: void onAutoChosen(); - void onSectionActivated(); void onRestartNow(); private: + void scaleChanged(); void createControls(); void setScale(DBIScale newScale); diff --git a/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp b/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp index 65486067b..b572e5c12 100644 --- a/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp +++ b/Telegram/SourceFiles/ui/widgets/discrete_slider.cpp @@ -30,11 +30,17 @@ DiscreteSlider::DiscreteSlider(QWidget *parent) : TWidget(parent) 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; - emit sectionActivated(); + if (_callback) { + _callback(); + } } } diff --git a/Telegram/SourceFiles/ui/widgets/discrete_slider.h b/Telegram/SourceFiles/ui/widgets/discrete_slider.h index 3235e00ec..51c3bc1ff 100644 --- a/Telegram/SourceFiles/ui/widgets/discrete_slider.h +++ b/Telegram/SourceFiles/ui/widgets/discrete_slider.h @@ -23,17 +23,19 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org namespace Ui { class DiscreteSlider : public TWidget { - Q_OBJECT - public: DiscreteSlider(QWidget *parent); + void addSection(const QString &label); + int activeSection() const { return _activeIndex; } void setActiveSection(int index); void setActiveSectionFast(int index); - void addSection(const QString &label); + + using SectionActivatedCallback = base::lambda_unique; + void setSectionActivatedCallback(SectionActivatedCallback &&callback); protected: void paintEvent(QPaintEvent *e) override; @@ -43,9 +45,6 @@ protected: int resizeGetHeight(int newWidth) override; -signals: - void sectionActivated(); - private: void resizeSections(int newWidth); int getIndexFromPosition(QPoint pos); @@ -62,6 +61,8 @@ private: QList
_sections; int _activeIndex = 0; + SectionActivatedCallback _callback; + bool _pressed = false; int _selected = 0; anim::ivalue a_left = { 0 }; diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index e63719950..8ac18e1a0 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -34,25 +34,26 @@ namespace Notifications { namespace Default { namespace { -// 3 desktop notifies at the same time. -constexpr int kNotifyWindowsCount = 3; - NeverFreedPointer ManagerInstance; -int notificationWidth() { - static auto result = ([] { - auto replyWidth = st::defaultBoxButton.font->width(lang(lng_notification_reply).toUpper()) - st::defaultBoxButton.width; - auto textLeft = st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft; - auto minWidth = textLeft + replyWidth + st::boxButtonPadding.right(); - return qMax(st::notifyMinWidth, minWidth); - })(); - return result; -} - 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() { @@ -73,13 +74,69 @@ Manager::Manager() { 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()) { + if (!notification->checkLastInput(replying)) { waiting = true; } } @@ -89,14 +146,7 @@ void Manager::checkLastInput() { } void Manager::startAllHiding() { - auto hasReplyingNotification = false; - for_const (auto notification, _notifications) { - if (notification->isReplying()) { - hasReplyingNotification = true; - break; - } - } - if (!hasReplyingNotification) { + if (!hasReplyingNotification()) { int notHidingCount = 0; for_const (auto notification, _notifications) { if (notification->isShowing()) { @@ -123,13 +173,15 @@ void Manager::stopAllHiding() { void Manager::showNextFromQueue() { if (!_queuedNotifications.isEmpty()) { - int count = kNotifyWindowsCount; + int count = Global::NotificationsCount(); for_const (auto notification, _notifications) { if (notification->isUnlinked()) continue; --count; } if (count > 0) { - auto position = notificationStartPosition(); + auto startPosition = notificationStartPosition(); + auto startShift = 0; + auto shiftDirection = notificationShiftDirection(); do { auto queued = _queuedNotifications.front(); _queuedNotifications.pop_front(); @@ -140,7 +192,7 @@ void Manager::showNextFromQueue() { queued.author, queued.item, queued.forwardedCount, - position); + startPosition, startShift, shiftDirection); Platform::Notifications::defaultNotificationShown(notification.get()); _notifications.push_back(notification.release()); --count; @@ -155,27 +207,18 @@ void Manager::showNextFromQueue() { } } -QPoint Manager::notificationStartPosition() const { - auto r = psDesktopRect(); - auto x = r.x() + r.width() - notificationWidth() - st::notifyDeltaX; - auto y = r.y() + r.height(); - return QPoint(x, y); -} - void Manager::moveWidgets() { - auto startPosition = notificationStartPosition(); - auto top = startPosition.y(); - int firstLeft = 0, firstTopCurrent = 0, firstTop = 0, count = 0; + 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; - top -= notification->height() + st::notifyDeltaY; - notification->moveTop(top); + notification->changeShift(shift); + shift += notification->height() + st::notifyDeltaY; - firstLeft = notification->x(); - firstTopCurrent = notification->y(); - firstTop = top; + lastShiftCurrent = notification->currentShift(); + lastShift = shift; ++count; } @@ -183,9 +226,9 @@ void Manager::moveWidgets() { if (count > 1 || !_queuedNotifications.isEmpty()) { auto deltaY = st::notifyHideAll.height + st::notifyDeltaY; if (!_hideAll) { - _hideAll = new HideAllButton(QPoint(firstLeft, firstTopCurrent - deltaY)); + _hideAll = new HideAllButton(notificationStartPosition(), lastShiftCurrent, notificationShiftDirection()); } - _hideAll->moveTop(firstTop - deltaY); + _hideAll->changeShift(lastShift); _hideAll->stopHiding(); } else if (_hideAll) { _hideAll->startHidingFast(); @@ -196,18 +239,18 @@ void Manager::changeNotificationHeight(Notification *notification, int newHeight auto deltaHeight = newHeight - notification->height(); if (!deltaHeight) return; - notification->addToHeight(deltaHeight, Notification::AddToHeight::Above); + 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->addToTop(-deltaHeight); + notification->addToShift(deltaHeight); } } if (_hideAll) { - _hideAll->addToTop(-deltaHeight); + _hideAll->addToShift(deltaHeight); } } @@ -293,57 +336,56 @@ Manager::~Manager() { namespace internal { -Widget::Widget(QPoint position) : TWidget(nullptr) +Widget::Widget(QPoint startPosition, int shift, Direction shiftDirection) : TWidget(nullptr) , _opacityDuration(st::notifyFastAnim) , a_opacity(0, 1) , a_func(anim::linear) -, _a_appearance(animation(this, &Widget::step_appearance)) -, a_top(position.y()) -, _a_movement(animation(this, &Notification::step_movement)) { +, _a_opacity(animation(this, &Widget::step_opacity)) +, _startPosition(startPosition) +, _direction(shiftDirection) +, a_shift(shift) +, _a_shift(animation(this, &Widget::step_shift)) { setWindowOpacity(0.); setAttribute(Qt::WA_OpaquePaintEvent); setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint); setAttribute(Qt::WA_MacAlwaysShowToolWindow); - setAttribute(Qt::WA_NoSystemBackground, true); - setAttribute(Qt::WA_TranslucentBackground, true); - _a_appearance.start(); + _a_opacity.start(); } -void Widget::step_appearance(float64 ms, bool timer) { +void Widget::step_opacity(float64 ms, bool timer) { float64 dt = ms / float64(_opacityDuration); if (dt >= 1) { a_opacity.finish(); - _a_appearance.stop(); + _a_opacity.stop(); if (_hiding) { deleteLater(); } } else { a_opacity.update(dt, a_func); } - setWindowOpacity(a_opacity.current()); + updateOpacity(); update(); } -void Widget::step_movement(float64 ms, bool timer) { +void Widget::step_shift(float64 ms, bool timer) { float64 dt = ms / float64(st::notifyFastAnim); if (dt >= 1) { - a_top.finish(); + a_shift.finish(); } else { - a_top.update(dt, anim::linear); + a_shift.update(dt, anim::linear); } - move(x(), a_top.current()); - update(); + moveByShift(); } void Widget::hideSlow() { - animHide(st::notifySlowHide, st::notifySlowHideFunc); + hideAnimated(st::notifySlowHide, st::notifySlowHideFunc); } void Widget::hideFast() { - animHide(st::notifyFastAnim, anim::linear); + hideAnimated(st::notifyFastAnim, anim::linear); } void Widget::hideStop() { @@ -352,29 +394,39 @@ void Widget::hideStop() { a_func = anim::linear; a_opacity.start(1); _hiding = false; - _a_appearance.start(); + _a_opacity.start(); } } -void Widget::animHide(float64 duration, anim::transition func) { +void Widget::hideAnimated(float64 duration, anim::transition func) { _opacityDuration = duration; a_func = func; a_opacity.start(0); _hiding = true; - _a_appearance.start(); + _a_opacity.start(); } -void Widget::moveTop(int top) { - a_top.start(top); - _a_movement.start(); -} - -void Widget::addToHeight(int add, AddToHeight aboveOrBelow) { - int newHeight = height() + add; - if (aboveOrBelow == AddToHeight::Above) { - a_top.add(-add); +void Widget::updateOpacity() { + if (auto manager = ManagerInstance.data()) { + setWindowOpacity(a_opacity.current() * manager->demoMasterOpacity()); } - updateGeometry(x(), a_top.current(), width(), newHeight); +} + +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) { @@ -382,9 +434,21 @@ void Widget::updateGeometry(int x, int y, int width, int height) { update(); } -void Widget::addToTop(int add) { - a_top.add(add); - move(x(), a_top.current()); +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) { @@ -400,7 +464,7 @@ void Background::paintEvent(QPaintEvent *e) { 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 position) : Widget(position) +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) @@ -411,7 +475,8 @@ Notification::Notification(History *history, PeerData *peer, PeerData *author, H #endif // Q_OS_WIN && !Q_OS_WINRT , _close(this, st::notifyClose) , _reply(this, lang(lng_notification_reply), st::defaultBoxButton) { - updateGeometry(position.x(), position.y(), notificationWidth(), st::notifyMinHeight); + auto position = computePosition(st::notifyMinHeight); + updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight); _userpicLoaded = _peer ? _peer->userpicLoaded() : true; updateNotifyDisplay(); @@ -460,7 +525,7 @@ void Notification::prepareActionsCache() { _buttonsCache = App::pixmapFromImageInPlace(std_::move(actionsCacheImg)); } -bool Notification::checkLastInput() { +bool Notification::checkLastInput(bool hasReplyingNotifications) { if (!_waitingForInput) return true; auto wasUserInput = true; // TODO @@ -472,7 +537,7 @@ bool Notification::checkLastInput() { #endif // Q_OS_WIN && !Q_OS_WINRT if (wasUserInput) { _waitingForInput = false; - if (!isReplying()) { + if (!hasReplyingNotifications) { _hideTimer.start(st::notifyWaitLongHide); } return true; @@ -684,9 +749,6 @@ void Notification::changeHeight(int newHeight) { bool Notification::unlinkHistory(History *history) { auto unlink = _history && (history == _history || !history); if (unlink) { - if (_history->peer->id != 4456802837) { - int a = 0; - } hideFast(); _history = nullptr; _item = nullptr; @@ -748,10 +810,11 @@ Notification::~Notification() { } } -HideAllButton::HideAllButton(QPoint position) : Widget(position) { +HideAllButton::HideAllButton(QPoint startPosition, int shift, Direction shiftDirection) : Widget(startPosition, shift, shiftDirection) { setCursor(style::cur_pointer); - updateGeometry(position.x(), position.y(), notificationWidth(), st::notifyHideAll.height); + auto position = computePosition(st::notifyHideAll.height); + updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyHideAll.height); hide(); createWinId(); diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 6094b8037..10886ee8c 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -31,6 +31,7 @@ namespace Window { namespace Notifications { namespace Default { namespace internal { +class Widget; class Notification; class HideAllButton; } // namespace internal @@ -59,6 +60,7 @@ private: friend class Notification; using HideAllButton = internal::HideAllButton; friend class HideAllButton; + friend class internal::Widget; void doUpdateAll() override; void doShowNotification(HistoryItem *item, int forwardedCount) override; @@ -75,9 +77,14 @@ private: void stopAllHiding(); void checkLastInput(); - QPoint notificationStartPosition() const; + 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; @@ -105,46 +112,57 @@ private: using QueuedNotifications = QList; QueuedNotifications _queuedNotifications; + FloatAnimation _demoMasterOpacity; + }; namespace internal { class Widget : public TWidget { public: - Widget(QPoint position); + enum class Direction { + Up, + Down, + }; + Widget(QPoint startPosition, int shift, Direction shiftDirection); bool isShowing() const { - return _a_appearance.animating() && !_hiding; + return _a_opacity.animating() && !_hiding; } - void moveTop(int top); - enum class AddToHeight { - Above, - Below, - }; - void addToHeight(int add, AddToHeight aboveOrBelow); - void addToTop(int add); + 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 animHide(float64 duration, anim::transition func); - void step_appearance(float64 ms, bool timer); - void step_movement(float64 ms, bool timer); + 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; float64 _opacityDuration; anim::fvalue a_opacity; anim::transition a_func; - Animation _a_appearance; + Animation _a_opacity; - anim::ivalue a_top; - Animation _a_movement; + QPoint _startPosition; + Direction _direction; + anim::ivalue a_shift; + Animation _a_shift; }; @@ -161,7 +179,7 @@ class Notification : public Widget { Q_OBJECT public: - Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, QPoint position); + Notification(History *history, PeerData *peer, PeerData *author, HistoryItem *item, int forwardedCount, QPoint startPosition, int shift, Direction shiftDirection); void startHiding(); void stopHiding(); @@ -179,7 +197,7 @@ public: // Called only by Manager. void itemRemoved(HistoryItem *del); bool unlinkHistory(History *history = nullptr); - bool checkLastInput(); + bool checkLastInput(bool hasReplyingNotifications); ~Notification(); @@ -237,7 +255,7 @@ private: class HideAllButton : public Widget { public: - HideAllButton(QPoint position); + HideAllButton(QPoint startPosition, int shift, Direction shiftDirection); void startHiding(); void startHidingFast(); diff --git a/Telegram/SourceFiles/window/window.style b/Telegram/SourceFiles/window/window.style index c2b4a20d2..721d756c9 100644 --- a/Telegram/SourceFiles/window/window.style +++ b/Telegram/SourceFiles/window/window.style @@ -37,7 +37,7 @@ notifyTextTop: 7px; notifySlowHideFunc: transition(easeInCirc); notifyWaitLongHide: 3000; notifyFastAnim: 150; -notifyMinWidth: 316px; +notifyWidth: 320px; notifyMinHeight: 80px; notifyDeltaX: 6px; notifyDeltaY: 7px; From eb47b9468ce69fa5c3dd99636c82763eeeacd064 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 10:58:34 +0300 Subject: [PATCH 25/32] Various fixes. Copy inline keyboard when forwarding messages with a game. Don't show "Deleted Message" in service message with scores. Improved tiny web page previews. Ignore right button in emoji panel. --- Telegram/Resources/langs/lang.strings | 2 + Telegram/SourceFiles/history/history_item.cpp | 25 ++++++-- Telegram/SourceFiles/history/history_item.h | 19 +++--- .../history/history_media_types.cpp | 6 +- .../SourceFiles/history/history_message.cpp | 64 ++++++++++++++----- .../SourceFiles/history/history_message.h | 9 ++- Telegram/SourceFiles/localstorage.cpp | 4 ++ .../settings/settings_general_widget.cpp | 3 + Telegram/SourceFiles/stickers/emoji_pan.cpp | 10 ++- 9 files changed, 104 insertions(+), 38 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index c8384625e..38dfc2508 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -590,6 +590,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/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index f792eafd6..c4d8c2978 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -359,7 +359,7 @@ void HistoryMessageReplyMarkup::createFromButtonRows(const QVector()) { + 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(); @@ -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 3505b01f5..934e43bc6 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -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_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 50d10940a..7e7779f0d 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()); } @@ -2009,13 +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, scoreNumber, 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, scoreNumber, 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); diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index c52e6490c..0a1408c9b 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/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 9f43d60f4..bc71589ec 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -31,6 +31,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwidget.h" #include "mainwindow.h" #include "lang.h" +#include "application.h" #include "playerwidget.h" #include "apiwrap.h" @@ -1078,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: { diff --git a/Telegram/SourceFiles/settings/settings_general_widget.cpp b/Telegram/SourceFiles/settings/settings_general_widget.cpp index 4945dd5c8..9c5e66c59 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/stickers/emoji_pan.cpp b/Telegram/SourceFiles/stickers/emoji_pan.cpp index 900ea04da..63850ba28 100644 --- a/Telegram/SourceFiles/stickers/emoji_pan.cpp +++ b/Telegram/SourceFiles/stickers/emoji_pan.cpp @@ -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; @@ -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(); @@ -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(); From 15ee4b40dcaa4d94e5cba22b857b01b909833bc6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 16:14:02 +0300 Subject: [PATCH 26/32] Retina handling fixed in the new notifications. --- .../SourceFiles/boxes/notifications_box.cpp | 18 ++++++++++++++---- Telegram/SourceFiles/boxes/notifications_box.h | 2 ++ .../platform/mac/notifications_manager_mac.mm | 2 +- .../window/notifications_manager_default.cpp | 2 ++ .../window/notifications_manager_default.h | 8 ++++---- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Telegram/SourceFiles/boxes/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp index 2e9962411..90d32bc04 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.cpp +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -235,6 +235,13 @@ void NotificationsBox::prepareNotificationSampleSmall() { _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); @@ -247,14 +254,14 @@ void NotificationsBox::prepareNotificationSampleLarge() { 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); - 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); + 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); - static QString notifyText = st::dialogsTextFont->elided(lang(lng_notification_preview), itemWidth); + auto 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); @@ -262,8 +269,11 @@ void NotificationsBox::prepareNotificationSampleLarge() { p.setPen(st::dialogsNameFg); p.setFont(st::msgNameFont); - static QString notifyTitle = st::msgNameFont->elided(qsl("Telegram Desktop"), rectForName.width()); + 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)); diff --git a/Telegram/SourceFiles/boxes/notifications_box.h b/Telegram/SourceFiles/boxes/notifications_box.h index 9e978f4f7..36bcfdbce 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.h +++ b/Telegram/SourceFiles/boxes/notifications_box.h @@ -57,7 +57,9 @@ private: int getContentLeft() const; void prepareNotificationSampleSmall(); void prepareNotificationSampleLarge(); + void prepareNotificationSampleUserpic(); + QPixmap _notificationSampleUserpic; QPixmap _notificationSampleSmall; QPixmap _notificationSampleLarge; ScreenCorner _chosenCorner; diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index c92db9c02..947be7a81 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -95,7 +95,7 @@ namespace Platform { namespace Notifications { void start() { - if (cPlatform() != dbipMacOld) { + if (false && cPlatform() != dbipMacOld) { ManagerInstance.makeIfNull(); } } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 8ac18e1a0..f0b26ea49 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -515,6 +515,7 @@ void Notification::prepareActionsCache() { 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); @@ -611,6 +612,7 @@ void Notification::updateNotifyDisplay() { _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); } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 10886ee8c..e4dbfb83e 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -56,11 +56,11 @@ public: ~Manager(); private: - using Notification = internal::Notification; - friend class Notification; - using HideAllButton = internal::HideAllButton; - friend class HideAllButton; + 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; From 4369c2331476a26d1330da6567cab1097db4e824 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 16:24:19 +0300 Subject: [PATCH 27/32] Version 0.10.12.alpha: major notifications update. --- Telegram/Resources/langs/lang.strings | 1 + Telegram/Resources/winrc/Telegram.rc | 8 ++--- Telegram/Resources/winrc/Updater.rc | 8 ++--- Telegram/SourceFiles/application.cpp | 4 +-- .../SourceFiles/boxes/notifications_box.cpp | 15 +++++++++- Telegram/SourceFiles/core/version.h | 6 ++-- .../window/notifications_manager_default.cpp | 30 ++++++++++++------- .../window/notifications_manager_default.h | 2 ++ Telegram/build/version | 8 ++--- 9 files changed, 54 insertions(+), 28 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 38dfc2508..b4815a859 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -254,6 +254,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org "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"; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 1b2a0fdd7..7b071f53a 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,11,0 - PRODUCTVERSION 0,10,11,0 + FILEVERSION 0,10,12,0 + PRODUCTVERSION 0,10,12,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.11.0" + VALUE "FileVersion", "0.10.12.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.11.0" + VALUE "ProductVersion", "0.10.12.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index def0bd48c..89d66d002 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,11,0 - PRODUCTVERSION 0,10,11,0 + FILEVERSION 0,10,12,0 + PRODUCTVERSION 0,10,12,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.11.0" + VALUE "FileVersion", "0.10.12.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.11.0" + VALUE "ProductVersion", "0.10.12.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index b3f648c80..d8616fe18 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -1085,8 +1085,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 { diff --git a/Telegram/SourceFiles/boxes/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp index 90d32bc04..70c05eec1 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.cpp +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -84,14 +84,27 @@ private: _owner->removeSample(this); } hide(); - deleteLater(); + 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; }; diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index 5c49b9b9d..e3ef0cebd 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10011; -constexpr str_const AppVersionStr = "0.10.11"; -constexpr bool AppAlphaVersion = false; +constexpr int AppVersion = 10012; +constexpr str_const AppVersionStr = "0.10.12"; +constexpr bool AppAlphaVersion = true; constexpr uint64 AppBetaVersion = BETA_VERSION_MACRO; diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index f0b26ea49..5932eefbb 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -296,9 +296,12 @@ void Manager::doClearAllFast() { _queuedNotifications.clear(); auto notifications = createAndSwap(_notifications); for_const (auto notification, notifications) { - notification->deleteLater(); + delete notification; + } + if (_hideAll) { + auto hideAll = createAndSwap(_hideAll); + delete hideAll; } - showNextFromQueue(); } void Manager::doClearFromHistory(History *history) { @@ -347,21 +350,33 @@ Widget::Widget(QPoint startPosition, int shift, Direction shiftDirection) : TWid , _a_shift(animation(this, &Widget::step_shift)) { setWindowOpacity(0.); - setAttribute(Qt::WA_OpaquePaintEvent); - 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) { - deleteLater(); + destroyDelayed(); } } else { a_opacity.update(dt, a_func); @@ -500,11 +515,6 @@ Notification::Notification(History *history, PeerData *peer, PeerData *author, H prepareActionsCache(); - setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::NoDropShadowWindowHint); - setAttribute(Qt::WA_MacAlwaysShowToolWindow); - setAttribute(Qt::WA_NoSystemBackground, true); - setAttribute(Qt::WA_TranslucentBackground, true); - show(); } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index e4dbfb83e..1a2dbd069 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -148,12 +148,14 @@ protected: 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; diff --git a/Telegram/build/version b/Telegram/build/version index 6eec02a3c..98c0ccfbe 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10011 +AppVersion 10012 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.11 -AppVersionStr 0.10.11 -AlphaChannel 0 +AppVersionStrSmall 0.10.12 +AppVersionStr 0.10.12 +AlphaChannel 1 BetaVersion 0 From 3c84899edf6f9ba4a0d144afba0b1cc98535c669 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 16:37:31 +0300 Subject: [PATCH 28/32] Version 0.10.12.alpha: returned native macOS notifications for 10.8+ --- Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index 947be7a81..c92db9c02 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -95,7 +95,7 @@ namespace Platform { namespace Notifications { void start() { - if (false && cPlatform() != dbipMacOld) { + if (cPlatform() != dbipMacOld) { ManagerInstance.makeIfNull(); } } From 4a9821117b46a81a875309c5e373b11fcb73d5e5 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 17:28:37 +0300 Subject: [PATCH 29/32] Version 0.10.12.alpha: no new settings link for macOS 10.8+ version. --- .../settings/settings_notifications_widget.cpp | 9 +++++++++ .../settings/settings_notifications_widget.h | 1 + Telegram/build/deploy.sh | 12 +++++------- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp index 3db9684e1..6aa9c61b1 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.cpp @@ -62,6 +62,15 @@ void NotificationsWidget::createControls() { 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()) { diff --git a/Telegram/SourceFiles/settings/settings_notifications_widget.h b/Telegram/SourceFiles/settings/settings_notifications_widget.h index dd07c6e3f..5bc3c28d9 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_widget.h +++ b/Telegram/SourceFiles/settings/settings_notifications_widget.h @@ -41,6 +41,7 @@ private slots: private: void createControls(); + void createNotificationsControls(); void desktopEnabledUpdated(); void viewParamUpdated(); diff --git a/Telegram/build/deploy.sh b/Telegram/build/deploy.sh index 0ac8f307b..911eabd5a 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 From f1d52c12aea0313bf444d2bf6348a7f131a844f8 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 19:45:45 +0300 Subject: [PATCH 30/32] Version 0.10.13.alpha: crash fix in custom notifications. Not sending inline bot request drafts to server by timeout. --- Telegram/Resources/winrc/Telegram.rc | 8 ++--- Telegram/Resources/winrc/Updater.rc | 8 ++--- Telegram/SourceFiles/application.cpp | 10 +++---- Telegram/SourceFiles/boxes/addcontactbox.cpp | 2 +- .../SourceFiles/boxes/notifications_box.cpp | 4 +-- Telegram/SourceFiles/config.h | 2 +- Telegram/SourceFiles/core/observer.h | 8 ++--- Telegram/SourceFiles/core/utils.h | 29 +++++++------------ .../SourceFiles/core/vector_of_moveable.h | 6 ++-- Telegram/SourceFiles/core/version.h | 4 +-- .../history/history_media_types.cpp | 2 +- .../SourceFiles/history/history_media_types.h | 2 +- Telegram/SourceFiles/historywidget.cpp | 7 ++--- Telegram/SourceFiles/lang.h | 2 +- Telegram/SourceFiles/localstorage.cpp | 4 +-- Telegram/SourceFiles/logs.cpp | 3 +- .../SourceFiles/media/media_audio_loaders.cpp | 2 +- .../media/media_child_ffmpeg_loader.cpp | 2 +- .../SourceFiles/media/media_clip_ffmpeg.cpp | 2 +- .../SourceFiles/media/media_clip_qtgif.cpp | 2 +- Telegram/SourceFiles/mediaview.cpp | 2 +- .../SourceFiles/mtproto/connection_tcp.cpp | 2 +- Telegram/SourceFiles/observer_peer.cpp | 4 +-- .../SourceFiles/overview/overview_layout.cpp | 2 +- .../linux/notifications_manager_linux.cpp | 6 ++-- .../win/notifications_manager_win.cpp | 6 ++-- .../profile/profile_actions_widget.cpp | 2 +- .../SourceFiles/profile/profile_cover.cpp | 2 +- .../profile/profile_members_widget.cpp | 2 +- Telegram/SourceFiles/pspecific_mac.cpp | 4 +-- Telegram/SourceFiles/structs.cpp | 2 +- Telegram/SourceFiles/structs.h | 2 +- Telegram/SourceFiles/ui/animation.h | 4 +-- .../window/notifications_manager_default.cpp | 15 ++++++---- Telegram/build/version | 6 ++-- 35 files changed, 80 insertions(+), 90 deletions(-) diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index 7b071f53a..92a14d323 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,12,0 - PRODUCTVERSION 0,10,12,0 + 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.12.0" + VALUE "FileVersion", "0.10.13.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.12.0" + 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 89d66d002..8e0ae490b 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,12,0 - PRODUCTVERSION 0,10,12,0 + 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.12.0" + VALUE "FileVersion", "0.10.13.0" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.12.0" + VALUE "ProductVersion", "0.10.13.0" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index d8616fe18..21c6a3d09 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -336,8 +336,7 @@ void Application::closeApplication() { manager->clearAllFast(); } - delete AppObject; - AppObject = 0; + delete base::take(AppObject); Sandbox::finish(); @@ -1103,8 +1102,7 @@ void AppClass::checkMapVersion() { AppClass::~AppClass() { Shortcuts::finish(); - auto window = createAndSwap(_window); - delete window; + delete base::take(_window); Window::Notifications::finish(); @@ -1117,8 +1115,8 @@ AppClass::~AppClass() { MTP::finish(); AppObject = nullptr; - deleteAndMark(_uploader); - deleteAndMark(_translator); + delete base::take(_uploader); + delete base::take(_translator); Window::chatBackground()->reset(); diff --git a/Telegram/SourceFiles/boxes/addcontactbox.cpp b/Telegram/SourceFiles/boxes/addcontactbox.cpp index f97a39ff9..5e561ff33 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/notifications_box.cpp b/Telegram/SourceFiles/boxes/notifications_box.cpp index 70c05eec1..172e2b67f 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.cpp +++ b/Telegram/SourceFiles/boxes/notifications_box.cpp @@ -274,7 +274,7 @@ void NotificationsBox::prepareNotificationSampleLarge() { 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_preview), itemWidth); + 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); @@ -398,7 +398,7 @@ void NotificationsBox::mousePressEvent(QMouseEvent *e) { } void NotificationsBox::mouseReleaseEvent(QMouseEvent *e) { - auto isDownCorner = createAndSwap(_isDownCorner); + auto isDownCorner = base::take(_isDownCorner); if (isDownCorner && _isOverCorner && _downCorner == _overCorner && _downCorner != _chosenCorner) { _chosenCorner = _downCorner; update(); diff --git a/Telegram/SourceFiles/config.h b/Telegram/SourceFiles/config.h index 85eb99476..a9ef7f033 100644 --- a/Telegram/SourceFiles/config.h +++ b/Telegram/SourceFiles/config.h @@ -212,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; } diff --git a/Telegram/SourceFiles/core/observer.h b/Telegram/SourceFiles/core/observer.h index 5ba24d25c..7457372fb 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); @@ -255,7 +255,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); @@ -302,7 +302,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(); @@ -349,7 +349,7 @@ protected: } ~Subscriber() { - auto subscriptions = createAndSwap(_subscriptions); + auto subscriptions = base::take(_subscriptions); for (auto &subscription : subscriptions) { subscription.destroy(); } diff --git a/Telegram/SourceFiles/core/utils.h b/Telegram/SourceFiles/core/utils.h index 7fb79b1c0..01a450d98 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(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(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) { @@ -477,7 +468,7 @@ public: return _p; } T *release() { - return getPointerAndReset(_p); + return base::take(_p); } void reset(T *p = nullptr) { delete _p; @@ -520,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 7077237d4..a0965b114 100644 --- a/Telegram/SourceFiles/core/vector_of_moveable.h +++ b/Telegram/SourceFiles/core/vector_of_moveable.h @@ -34,9 +34,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(_size, other._size); diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index e3ef0cebd..bc9856a6c 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -24,7 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #define BETA_VERSION_MACRO (0ULL) -constexpr int AppVersion = 10012; -constexpr str_const AppVersionStr = "0.10.12"; +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/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index 934e43bc6..d49f6a1f4 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) diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h index 45c0ea3ea..68c913dc1 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/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 581d15b8e..c1b7511fa 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -3372,7 +3372,7 @@ void HistoryWidget::writeDrafts(Data::Draft **localDraft, Data::Draft **editDraf } } - if (!_editMsgId) { + if (!_editMsgId && !_inlineBot) { _saveCloudDraftTimer.start(SaveCloudDraftIdleTimeout); } } @@ -5985,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()); @@ -8863,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/lang.h b/Telegram/SourceFiles/lang.h index 4202e7845..e8e551900 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/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index bc71589ec..991e64aa6 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -2655,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: @@ -2931,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 fd83ba422..5565cecbd 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/media/media_audio_loaders.cpp b/Telegram/SourceFiles/media/media_audio_loaders.cpp index 491eb8cda..fed6ed7c6 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 b5b7e8194..20b645721 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 aef676db3..bd3abc4e0 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 6ab82b1e2..e82624691 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/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 96216cbc6..27fd69a07 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -619,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/mtproto/connection_tcp.cpp b/Telegram/SourceFiles/mtproto/connection_tcp.cpp index 9e64751a4..4d73feab1 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/observer_peer.cpp b/Telegram/SourceFiles/observer_peer.cpp index e4d463e5f..66dfb3602 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 b0c83da45..55260b1db 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -105,7 +105,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/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 6ff08d77a..15dd89891 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -226,7 +226,7 @@ void start() { } Manager *manager() { - if (Global::NativeNotifications()) { + if (Global::started() && Global::NativeNotifications()) { return ManagerInstance.data(); } return nullptr; @@ -412,7 +412,7 @@ void Manager::Impl::showNextNotification() { void Manager::Impl::clearAll() { _queuedNotifications.clear(); - auto temp = createAndSwap(_notifications); + auto temp = base::take(_notifications); for_const (auto ¬ifications, temp) { for_const (auto notification, notifications) { notification->close(); @@ -431,7 +431,7 @@ void Manager::Impl::clearFromHistory(History *history) { auto i = _notifications.find(history->peer->id); if (i != _notifications.cend()) { - auto temp = createAndSwap(i.value()); + auto temp = base::take(i.value()); _notifications.erase(i); for_const (auto notification, temp) { diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index c5746d3a3..4dbcb5e36 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -321,7 +321,7 @@ void start() { } Manager *manager() { - if (Global::NativeNotifications()) { + if (Global::started() && Global::NativeNotifications()) { return ManagerInstance.data(); } return nullptr; @@ -361,7 +361,7 @@ Manager::Impl::~Impl() { void Manager::Impl::clearAll() { if (!_notifier) return; - auto temp = createAndSwap(_notifications); + auto temp = base::take(_notifications); for_const (auto ¬ifications, temp) { for_const (auto ¬ification, notifications) { _notifier->Hide(notification.p.Get()); @@ -374,7 +374,7 @@ void Manager::Impl::clearFromHistory(History *history) { auto i = _notifications.find(history->peer->id); if (i != _notifications.cend()) { - auto temp = createAndSwap(i.value()); + auto temp = base::take(i.value()); _notifications.erase(i); for_const (auto ¬ification, temp) { diff --git a/Telegram/SourceFiles/profile/profile_actions_widget.cpp b/Telegram/SourceFiles/profile/profile_actions_widget.cpp index f8c04ae0f..ef4ee8465 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 76adaa96e..d9ac7434d 100644 --- a/Telegram/SourceFiles/profile/profile_cover.cpp +++ b/Telegram/SourceFiles/profile/profile_cover.cpp @@ -444,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 665b4dc01..022f96772 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 2ed9fd9b7..cf6a12e4a 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/structs.cpp b/Telegram/SourceFiles/structs.cpp index 43bd13f5d..90630ef31 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 { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index f75c8ade2..3e9f0d9fe 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/ui/animation.h b/Telegram/SourceFiles/ui/animation.h index eaa496fb8..1018053f2 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); @@ -323,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/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 5932eefbb..e1b3f1816 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -294,14 +294,11 @@ void Manager::doClearAll() { void Manager::doClearAllFast() { _queuedNotifications.clear(); - auto notifications = createAndSwap(_notifications); + auto notifications = base::take(_notifications); for_const (auto notification, notifications) { delete notification; } - if (_hideAll) { - auto hideAll = createAndSwap(_hideAll); - delete hideAll; - } + delete base::take(_hideAll); } void Manager::doClearFromHistory(History *history) { @@ -321,6 +318,12 @@ void Manager::doClearFromHistory(History *history) { } 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); @@ -866,7 +869,7 @@ void HideAllButton::mousePressEvent(QMouseEvent *e) { } void HideAllButton::mouseReleaseEvent(QMouseEvent *e) { - auto mouseDown = createAndSwap(_mouseDown); + auto mouseDown = base::take(_mouseDown); if (mouseDown && _mouseOver) { if (auto manager = ManagerInstance.data()) { manager->clearAll(); diff --git a/Telegram/build/version b/Telegram/build/version index 98c0ccfbe..4b2feb611 100644 --- a/Telegram/build/version +++ b/Telegram/build/version @@ -1,6 +1,6 @@ -AppVersion 10012 +AppVersion 10013 AppVersionStrMajor 0.10 -AppVersionStrSmall 0.10.12 -AppVersionStr 0.10.12 +AppVersionStrSmall 0.10.13 +AppVersionStr 0.10.13 AlphaChannel 1 BetaVersion 0 From 6798b86655a170e25ca7391148c118fed2223ae2 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 7 Oct 2016 20:02:13 +0300 Subject: [PATCH 31/32] Version 0.10.13.alpha: removed Reply button for hidden text notifies. --- .../window/notifications_manager_default.cpp | 18 +++++++++++++----- .../window/notifications_manager_default.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index e1b3f1816..6dda3e38e 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -615,10 +615,10 @@ void Notification::updateNotifyDisplay() { { 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); + 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 (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { _history->peer->loadUserpic(true, true); @@ -675,6 +675,9 @@ void Notification::updateNotifyDisplay() { } _cache = App::pixmapFromImageInPlace(std_::move(img)); + if (!canReply()) { + toggleActionButtons(false); + } update(); } @@ -690,6 +693,7 @@ void Notification::updatePeerPhoto() { _peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); } _cache = App::pixmapFromImageInPlace(std_::move(img)); + update(); } void Notification::itemRemoved(HistoryItem *deleted) { @@ -699,6 +703,10 @@ void Notification::itemRemoved(HistoryItem *deleted) { } } +bool Notification::canReply() const { + return (_item != nullptr) && !App::passcoded() && (Global::NotifyView() <= dbinvShowPreview); +} + void Notification::unlinkHistoryInManager() { if (auto manager = ManagerInstance.data()) { manager->unlinkFromShown(this); @@ -776,7 +784,7 @@ void Notification::enterEvent(QEvent *e) { if (auto manager = ManagerInstance.data()) { manager->stopAllHiding(); } - if (!_replyArea) { + if (!_replyArea && canReply()) { toggleActionButtons(true); } } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 1a2dbd069..80a67acc4 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -216,6 +216,8 @@ private slots: void onReplyCancel(); private: + bool canReply() const; + void unlinkHistoryInManager(); void toggleActionButtons(bool visible); void prepareActionsCache(); From 377d333f1c08e546b93c009c6ee74b220fa964e1 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 8 Oct 2016 11:38:53 +0300 Subject: [PATCH 32/32] Using same notification options for all notification managers. --- .../platform/linux/main_window_linux.cpp | 7 ++++++ .../linux/notifications_manager_linux.cpp | 18 ++++++------- .../linux/notifications_manager_linux.h | 2 +- .../platform/mac/notifications_manager_mac.h | 2 +- .../platform/mac/notifications_manager_mac.mm | 12 ++++----- .../win/notifications_manager_win.cpp | 14 +++++------ .../platform/win/notifications_manager_win.h | 2 +- .../window/notifications_manager.cpp | 25 +++++++++++-------- .../window/notifications_manager.h | 9 ++++++- .../window/notifications_manager_default.cpp | 13 ++++++---- .../window/notifications_manager_default.h | 1 + 11 files changed, 64 insertions(+), 41 deletions(-) diff --git a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp index 42e825463..42e4716ef 100644 --- a/Telegram/SourceFiles/platform/linux/main_window_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/main_window_linux.cpp @@ -252,7 +252,14 @@ 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(); diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp index 15dd89891..a15a76c36 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.cpp @@ -247,7 +247,7 @@ class Manager::Impl { public: bool init(); - void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + 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); @@ -267,7 +267,7 @@ private: MsgId msgId = 0; QString title; QString body; - bool showUserpic = false; + bool hideNameAndPhoto = false; }; QString _serverName; @@ -327,7 +327,7 @@ bool Manager::Impl::init() { return !_serverName.isEmpty(); } -void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { +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); @@ -341,7 +341,7 @@ void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString notification.msgId = msgId; notification.title = titleText; notification.body = bodyText; - notification.showUserpic = showUserpic; + notification.hideNameAndPhoto = hideNameAndPhoto; _queuedNotifications.push_back(notification); showNextNotification(); @@ -378,10 +378,10 @@ void Manager::Impl::showNextNotification() { } StorageKey key; - if (data.showUserpic) { - key = data.peer->userpicUniqueKey(); - } else { + if (data.hideNameAndPhoto) { key = StorageKey(0, 0); + } else { + key = data.peer->userpicUniqueKey(); } notification->setImage(_cachedUserpics.get(key, data.peer)); @@ -475,8 +475,8 @@ bool Manager::hasActionsSupport() const { Manager::~Manager() = default; -void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +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() { diff --git a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h index 8b52c6328..79f9c0259 100644 --- a/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h +++ b/Telegram/SourceFiles/platform/linux/notifications_manager_linux.h @@ -48,7 +48,7 @@ public: ~Manager(); protected: - void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + 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; diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h index bb466f1b8..17d033d7c 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.h @@ -42,7 +42,7 @@ public: ~Manager(); protected: - void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + 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; diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index c92db9c02..a1ddf0896 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -118,7 +118,7 @@ void defaultNotificationShown(QWidget *widget) { class Manager::Impl { public: Impl(); - void showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + 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(); @@ -133,7 +133,7 @@ private: Manager::Impl::Impl() : _delegate([[NotificationDelegate alloc] init]) { } -void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { +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]; @@ -147,13 +147,13 @@ void Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString [notification setTitle:Q2NSString(title)]; [notification setSubtitle:Q2NSString(subtitle)]; [notification setInformativeText:Q2NSString(msg)]; - if (showUserpic && [notification respondsToSelector:@selector(setContentImage:)]) { + if (!hideNameAndPhoto && [notification respondsToSelector:@selector(setContentImage:)]) { auto userpic = peer->genUserpic(st::notifyMacPhotoSize); NSImage *img = [qt_mac_create_nsimage(userpic) autorelease]; [notification setContentImage:img]; } - if (showReplyButton && [notification respondsToSelector:@selector(setHasReplyButton:)]) { + if (!hideReplyButton && [notification respondsToSelector:@selector(setHasReplyButton:)]) { [notification setHasReplyButton:YES]; } @@ -214,8 +214,8 @@ void Manager::updateDelegate() { Manager::~Manager() = default; -void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +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() { diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp index 4dbcb5e36..337af08cd 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.cpp @@ -337,7 +337,7 @@ void finish() { class Manager::Impl { public: - bool showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton); + 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); @@ -403,7 +403,7 @@ void Manager::Impl::clearNotification(PeerId peerId, MsgId msgId) { } } -bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { +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; @@ -416,10 +416,10 @@ bool Manager::Impl::showNotification(PeerData *peer, MsgId msgId, const QString if (!SUCCEEDED(hr)) return false; StorageKey key; - if (showUserpic) { - key = peer->userpicUniqueKey(); - } else { + if (hideNameAndPhoto) { key = StorageKey(0, 0); + } else { + key = peer->userpicUniqueKey(); } auto userpicPath = _cachedUserpics.get(key, peer); auto userpicPathWide = QDir::toNativeSeparators(userpicPath).toStdWString(); @@ -514,8 +514,8 @@ void Manager::clearNotification(PeerId peerId, MsgId msgId) { Manager::~Manager() = default; -void Manager::doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) { - _impl->showNotification(peer, msgId, title, subtitle, showUserpic, msg, showReplyButton); +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() { diff --git a/Telegram/SourceFiles/platform/win/notifications_manager_win.h b/Telegram/SourceFiles/platform/win/notifications_manager_win.h index 37597a175..ae5e396bb 100644 --- a/Telegram/SourceFiles/platform/win/notifications_manager_win.h +++ b/Telegram/SourceFiles/platform/win/notifications_manager_win.h @@ -44,7 +44,7 @@ public: ~Manager(); protected: - void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) override; + 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; diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index e72a81336..03b88ae1c 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -47,6 +47,16 @@ void 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()) { @@ -87,18 +97,13 @@ void Manager::notificationReplied(PeerId peerId, MsgId msgId, const QString &rep } void NativeManager::doShowNotification(HistoryItem *item, int forwardedCount) { - auto hideEverything = (App::passcoded() || Global::ScreenIsLocked()); - auto hideName = hideEverything || (Global::NotifyView() > dbinvShowName); - auto hidePreview = hideEverything || (Global::NotifyView() > dbinvShowPreview); + auto options = getNotificationOptions(item); - QString title = hideName ? qsl("Telegram Desktop") : item->history()->peer->name; - QString subtitle = hideName ? QString() : item->notificationHeader(); - bool showUserpic = hideName ? false : true; + 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)); - QString msg = hidePreview ? lang(lng_notification_preview) : (forwardedCount < 2 ? item->notificationText() : lng_forward_messages(lt_count, forwardedCount)); - bool showReplyButton = hidePreview ? false : item->history()->peer->canWrite(); - - doShowNativeNotification(item->history()->peer, item->id, title, subtitle, showUserpic, msg, showReplyButton); + doShowNativeNotification(item->history()->peer, item->id, title, subtitle, text, options.hideNameAndPhoto, options.hideReplyButton); } } // namespace Notifications diff --git a/Telegram/SourceFiles/window/notifications_manager.h b/Telegram/SourceFiles/window/notifications_manager.h index 3ea25c74a..421d4d6c2 100644 --- a/Telegram/SourceFiles/window/notifications_manager.h +++ b/Telegram/SourceFiles/window/notifications_manager.h @@ -53,6 +53,13 @@ public: 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: @@ -81,7 +88,7 @@ protected: } void doShowNotification(HistoryItem *item, int forwardedCount) override; - virtual void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, bool showUserpic, const QString &msg, bool showReplyButton) = 0; + virtual void doShowNativeNotification(PeerData *peer, MsgId msgId, const QString &title, const QString &subtitle, const QString &msg, bool hideNameAndPhoto, bool hideReplyButton) = 0; }; diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 6dda3e38e..e9c2e6557 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -608,6 +608,9 @@ void Notification::actionsOpacityCallback() { 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()); @@ -620,7 +623,7 @@ void Notification::updateNotifyDisplay() { 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 (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { + if (!options.hideNameAndPhoto) { _history->peer->loadUserpic(true, true); _history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width()); } else { @@ -632,14 +635,14 @@ void Notification::updateNotifyDisplay() { 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 (!options.hideNameAndPhoto) { if (auto chatTypeIcon = Dialogs::Layout::ChatTypeIcon(_history->peer, false)) { chatTypeIcon->paint(p, rectForName.topLeft(), w); rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip); } } - if (!App::passcoded() && Global::NotifyView() <= dbinvShowPreview) { + 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); @@ -665,7 +668,7 @@ void Notification::updateNotifyDisplay() { } p.setPen(st::dialogsNameFg); - if (!App::passcoded() && Global::NotifyView() <= dbinvShowName) { + if (!options.hideNameAndPhoto) { _history->peer->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); } else { p.setFont(st::msgNameFont); @@ -704,7 +707,7 @@ void Notification::itemRemoved(HistoryItem *deleted) { } bool Notification::canReply() const { - return (_item != nullptr) && !App::passcoded() && (Global::NotifyView() <= dbinvShowPreview); + return !_hideReplyButton && (_item != nullptr) && !App::passcoded() && (Global::NotifyView() <= dbinvShowPreview); } void Notification::unlinkHistoryInManager() { diff --git a/Telegram/SourceFiles/window/notifications_manager_default.h b/Telegram/SourceFiles/window/notifications_manager_default.h index 80a67acc4..0181d85e0 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.h +++ b/Telegram/SourceFiles/window/notifications_manager_default.h @@ -229,6 +229,7 @@ private: QPixmap _cache; + bool _hideReplyButton = false; bool _actionsVisible = false; FloatAnimation a_actionsOpacity; QPixmap _buttonsCache;