Merge branch 'game_media' into player

Conflicts:
	Telegram/SourceFiles/core/basic_types.h
	Telegram/SourceFiles/sysbuttons.h
	Telegram/SourceFiles/title.cpp
This commit is contained in:
John Preston 2016-09-29 16:48:43 +03:00
commit 5b3ac58578
64 changed files with 1674 additions and 1612 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

After

Width:  |  Height:  |  Size: 234 KiB

View File

@ -558,37 +558,6 @@ btnDefLink: linkButton {
overFont: linkOverFont;
}
cbDefFlat: flatCheckbox {
textColor: #000;
bgColor: transparent;
disColor: #999;
height: 22px;
textTop: 1px;
textLeft: 34px;
font: font(fsize);
duration: 200;
bgFunc: transition(easeOutCirc);
cursor: cursor(pointer);
disabledCursor: cursor(default);
imageRect: sprite(142px, 43px, 22px, 22px);
chkImageRect: sprite(120px, 68px, 22px, 22px);
overImageRect: sprite(142px, 68px, 22px, 22px);
chkOverImageRect: sprite(120px, 68px, 22px, 22px);
disImageRect: sprite(142px, 43px, 22px, 22px);
chkDisImageRect: sprite(120px, 43px, 22px, 22px);
imagePos: point(0px, 0px);
}
rbDefFlat: flatCheckbox(cbDefFlat) {
chkImageRect: sprite(165px, 68px, 22px, 22px);
chkOverImageRect: sprite(165px, 68px, 22px, 22px);
chkDisImageRect: sprite(165px, 43px, 22px, 22px);
}
inpDefFont: font(17px);
inpDefFlat: flatInput {
textColor: #000;
@ -816,28 +785,7 @@ introErrLabel: flatLabel(labelDefFlat) {
align: align(center);
}
setWidth: 356px;
setTop: 26px;
setNameLeft: 3px;
setNameTop: 5px;
setNameFont: font(18px);
setStatusTop: 35px;
setStatusLeft: 3px;
setStatusFont: font(14px);
setPhotoSize: 120px;
setHeaderFont: font(17px);
setHeaderColor: black;
setHeaderSkip: 60px;
setHeaderLeft: -1px;
setHeaderTop: 26px;
setLittleSkip: 9px;
setSectionSkip: 25px;
setContactInfoLeft: 150px;
setVersionHeight: 41px;
setVersionLeft: 36px;
setVersionTop: 3px;
setVersionColor: #999;
setBottom: 130px;
setScroll: flatScroll(scrollDef) {
bottomsh: 0px;
topsh: 0px;
@ -854,92 +802,11 @@ setClose: iconedButton(btnDefIconed) {
height: 43px;
}
setClosePos: point(32px, 32px);
setPhotoImg: sprite(0px, 218px, 120px, 120px);
setOverPhotoImg: sprite(122px, 218px, 120px, 120px);
setPhotoDuration: 150;
setPadding: 26px;
setBG: #FFF;
setSh: #000;
setTitleFrom: point(20px, 20px);
setTitleFont: font(24px);
setTitleColor: #000;
setNameInput: flatInput(inpDefFlat) {
font: font(fsize);
height: 25px;
width: 170px;
textMrg: margins(3px, 3px, 3px, 3px);
}
setErrBG: #ffa5a5;
setErrColor: #d84d4d;
setErrHeight: 30px;
setErrFont: font(fsize);
setGoodColor: #4ab44a;
setBackgroundSize: 120px;
btnSetUpload: flatButton(btnDefNext, btnDefBig) {
width: 206px;
height: 42px;
font: font(18px);
overFont: font(18px);
textTop: 9px;
overTextTop: 9px;
downTextTop: 10px;
}
btnEditSave: flatButton(btnSetUpload) {
width: 115px;
}
btnEditCancel: flatButton(btnDefFlat, btnDefBig) {
color: #666d78;
overColor: #666d78;
downColor: #50565e;
bgColor: rgba(0, 0, 0, 63);
overBgColor: rgba(0, 0, 0, 47);
downBgColor: rgba(0, 0, 0, 95);
width: 115px;
height: 40px;
textTop: 9px;
overTextTop: 9px;
downTextTop: 10px;
font: font(18px);
overFont: font(18px);
}
btnLogout: flatButton(btnDefFlat, btnDefBig) {
color: white;
overColor: white;
downColor: white;
bgColor: #db6352;
overBgColor: #d15948;
downBgColor: #c74d3b;
width: 148px;
height: 42px;
textTop: 8px;
overTextTop: 8px;
downTextTop: 9px;
font: font(18px);
overFont: font(18px);
}
searchFlatInput: flatInput(inpDefGray) {
font: font(fsize);
bgColor: #f2f2f2;
phColor: #949494;
phFocusColor: #a4a4a4;
imgRect: sprite(227px, 21px, 24px, 24px);
}
noContactsHeight: 100px;
noContactsFont: font(fsize);
noContactsColor: #777;
@ -956,7 +823,13 @@ dlgActiveChatImg: sprite(104px, 37px, 16px, 11px);
dlgChannelImg: sprite(105px, 1px, 12px, 11px);
dlgActiveChannelImg: sprite(105px, 14px, 12px, 11px);
dlgFilter: flatInput(searchFlatInput) {
dlgFilter: flatInput(inpDefGray) {
font: font(fsize);
bgColor: #f2f2f2;
phColor: #949494;
phFocusColor: #a4a4a4;
imgRect: sprite(227px, 21px, 24px, 24px);
width: 240px;
height: 34px;
textMrg: margins(34px, 2px, 34px, 4px);
@ -1136,7 +1009,7 @@ msgInvDblCheckImg: sprite(300px, 65px, 20px, 20px);
msgInvViewsImg: sprite(104px, 59px, 16px, 11px);
msgInvSendingViewsImg: sprite(104px, 114px, 16px, 11px);
msgDateSpace: 19px;
msgDateSpace: 12px;
msgDateCheckSpace: 4px;
msgDateViewsSpace: 11px;
msgDateDelta: point(2px, 5px);
@ -1818,13 +1691,6 @@ dragPadding: margins(20px, 10px, 20px, 10px);
dragHeight: 72px;
dpiSlider: slider {
color: #ccc;
thickness: 2px;
width: 260px;
bar: sprite(0px, 104px, 9px, 22px);
}
dpiActive: black;
dpiInactive: #999;
dpiFont1: linkFont;

View File

@ -202,14 +202,6 @@ countryInput {
align: align;
}
slider {
color: color;
thickness: pixels;
width: pixels;
bar: sprite;
}
flatLabel {
font: font;
margin: margins;

View File

@ -581,8 +581,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_location" = "a location mark";
"lng_action_pinned_media_sticker" = "a sticker";
"lng_action_pinned_media_emoji_sticker" = "a {emoji} sticker";
"lng_action_pinned_media_game" = "a game «{game}»";
"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_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.";

View File

@ -580,7 +580,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_contact" = "einen Kontakt";
"lng_action_pinned_media_location" = "einen Standort";
"lng_action_pinned_media_sticker" = "einen Sticker";
"lng_action_game_score" = "{from} erzielte {count:Punkte|Punkt|Punkte} bei {game}";
"lng_action_pinned_media_emoji_sticker" = "einen {emoji} Sticker";
"lng_action_pinned_media_game" = "das Spiel «{game}»";
"lng_action_game_score" = "{from} erzielte {count:# Punkte|# Punkt|# Punkte} bei {game}";
"lng_action_game_you_scored" = "Du hast {count:# Punkte|# Punkt|# Punkte} bei {game} erzielt";
"lng_profile_migrate_reached" = "Limit von {count:_not_used_|# Mitglied|# Mitgliedern} erreicht";
"lng_profile_migrate_body" = "Um das Limit aufzuheben, ändere die Gruppe in eine Supergruppe.";
@ -774,6 +777,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_bot_groups_not_found" = "Keine Gruppen gefunden";
"lng_bot_sure_invite" = "Den Bot zu «{group}» hinzufügen?";
"lng_bot_already_in_group" = "Der Bot ist schon in dieser Gruppe.";
"lng_bot_choose_chat" = "Chat auswählen";
"lng_bot_no_chats" = "Du hast keine Chats";
"lng_bot_chats_not_found" = "Keine Chats gefunden";
"lng_bot_sure_share_game" = "Das Spiel mit {user} teilen?";
"lng_bot_sure_share_game_group" = "Das Spiel mit «{group}» teilen?";
"lng_typing" = "tippt";
"lng_user_typing" = "{user} tippt";
@ -808,6 +816,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Bilder auswählen";
"lng_game_tag" = "Spiel";
"lng_context_view_profile" = "Profil öffnen";
"lng_context_view_group" = "Gruppeninfo zeigen";

View File

@ -580,7 +580,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_contact" = "un contacto";
"lng_action_pinned_media_location" = "una ubicación";
"lng_action_pinned_media_sticker" = "un sticker";
"lng_action_game_score" = "{from} ha conseguido {count:# puntos|# punto|# puntos} en {game}";
"lng_action_pinned_media_emoji_sticker" = "un {emoji} sticker";
"lng_action_pinned_media_game" = "el juego «{game}»";
"lng_action_game_score" = "{from} consiguió {count:# puntos|# punto|# puntos} en {game}";
"lng_action_game_you_scored" = "Conseguiste {count:# puntos|# punto|#puntos} en {game}";
"lng_profile_migrate_reached" = "Límite de {count:_not_used_|# miembro|# miembros} alcanzado";
"lng_profile_migrate_body" = "Para superar este límite, puedes convertir tu grupo en un supergrupo.";
@ -774,6 +777,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_bot_groups_not_found" = "No se encontraron grupos";
"lng_bot_sure_invite" = "¿Añadir el bot a «{group}»?";
"lng_bot_already_in_group" = "El bot ya es un miembro del grupo.";
"lng_bot_choose_chat" = "Elige un chat";
"lng_bot_no_chats" = "No tienes chats";
"lng_bot_chats_not_found" = "No se encontraron chats";
"lng_bot_sure_share_game" = "¿Compartir el juego con {user}?";
"lng_bot_sure_share_game_group" = "¿Compartir el juego en «{group}»?";
"lng_typing" = "escribiendo";
"lng_user_typing" = "{user} está escribiendo";
@ -808,6 +816,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Elegir imágenes";
"lng_game_tag" = "Juego";
"lng_context_view_profile" = "Ver información";
"lng_context_view_group" = "Ver información";

View File

@ -580,7 +580,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_contact" = "un contatto";
"lng_action_pinned_media_location" = "una posizione";
"lng_action_pinned_media_sticker" = "uno sticker";
"lng_action_game_score" = "{from} ha segnato {count:# punti|# punto|# punti} in {game}";
"lng_action_pinned_media_emoji_sticker" = "uno {emoji} sticker";
"lng_action_pinned_media_game" = "il gioco «{game}»";
"lng_action_game_score" = "{from} ha totalizzato {count:# punti|# punto|# punti} a {game}";
"lng_action_game_you_scored" = "Hai totalizzato {count:# punti|# punto|# punti} a {game}";
"lng_profile_migrate_reached" = "Limite di {count:_not_used_|# membro|# membri} raggiunto";
"lng_profile_migrate_body" = "Per superare questo limite, puoi aggiornare il gruppo a supergruppo.";
@ -774,6 +777,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_bot_groups_not_found" = "Nessun gruppo trovato";
"lng_bot_sure_invite" = "Aggiungere il bot a «{group}»?";
"lng_bot_already_in_group" = "Questo bot è già membro del gruppo.";
"lng_bot_choose_chat" = "Scegli chat";
"lng_bot_no_chats" = "Non hai chat";
"lng_bot_chats_not_found" = "Nessuna chat trovata";
"lng_bot_sure_share_game" = "Condividere questo gioco con {user}?";
"lng_bot_sure_share_game_group" = "Condividere questo gioco con «{group}»?";
"lng_typing" = "sta scrivendo";
"lng_user_typing" = "{user} sta scrivendo";
@ -808,6 +816,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Scegli immagini";
"lng_game_tag" = "Gioco";
"lng_context_view_profile" = "Visualizza profilo";
"lng_context_view_group" = "Visualizza info gruppo";

View File

@ -580,7 +580,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_contact" = "연락처 정보";
"lng_action_pinned_media_location" = "위치 마크";
"lng_action_pinned_media_sticker" = "스티커";
"lng_action_pinned_media_emoji_sticker" = " {emoji} 스티커";
"lng_action_pinned_media_game" = " «{game}» 게임";
"lng_action_game_score" = "{game} 에서 {from} 님이 {count:#|#|#} 점 획득";
"lng_action_game_you_scored" = "{game} 에서 {count:#|#|#} 점 획득";
"lng_profile_migrate_reached" = "{count:_not_used_|# 명|# 명} 한계치에 도달 되었습니다.";
"lng_profile_migrate_body" = "제한을 초과하고 싶으실 경우, 슈퍼그룹으로 그룹 업그레이드가 가능합니다.";
@ -774,6 +777,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_bot_groups_not_found" = "그룹을 찾을 수 없습니다.";
"lng_bot_sure_invite" = "<<{group}>>에 봇을 추가 하시겠습니까?";
"lng_bot_already_in_group" = "봇이 이미 그룹의 멤버입니다.";
"lng_bot_choose_chat" = "채팅방 선택";
"lng_bot_no_chats" = "채팅방이 없습니다.";
"lng_bot_chats_not_found" = "채팅방을 찾 을 수 없음";
"lng_bot_sure_share_game" = "{user}에게 게임을 공유하겠습니까?";
"lng_bot_sure_share_game_group" = " «{group}»에게 게임을 공유하겠습니까?";
"lng_typing" = "입력중";
"lng_user_typing" = "{user}님이 입력중입니다.";
@ -808,6 +816,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "이미지 선택";
"lng_game_tag" = "게임";
"lng_context_view_profile" = "프로필 보기";
"lng_context_view_group" = "그룹 정보 보기";

View File

@ -580,7 +580,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_contact" = "een contact";
"lng_action_pinned_media_location" = "een locatie";
"lng_action_pinned_media_sticker" = "een sticker";
"lng_action_game_score" = "{from} heeft met {game} {count:#punten|#punt|#punten} behaald";
"lng_action_pinned_media_emoji_sticker" = "een {emoji} sticker";
"lng_action_pinned_media_game" = "het spel «{game}»";
"lng_action_game_score" = "{from} heeft met {game} {count:# punten|# punt|# punten} behaald";
"lng_action_game_you_scored" = "Je hebt met {game} {count:# punten|# punt|# punten} behaald";
"lng_profile_migrate_reached" = "{count:_not_used_|# lid |# leden} limiet bereikt";
"lng_profile_migrate_body" = "Wil je een hogere limiet? Waardeer op naar een supergroep.";
@ -774,6 +777,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_bot_groups_not_found" = "Geen groepen gevonden";
"lng_bot_sure_invite" = "De bot toevoegen aan \"{group}\"?";
"lng_bot_already_in_group" = "Deze bot is al een groepslid.";
"lng_bot_choose_chat" = "Kies chat";
"lng_bot_no_chats" = "Je hebt nog geen chats";
"lng_bot_chats_not_found" = "Geen chats gevonden";
"lng_bot_sure_share_game" = "Spel met {user} delen?";
"lng_bot_sure_share_game_group" = "Spel met «{group}» delen?";
"lng_typing" = "aan het typen";
"lng_user_typing" = "{user} is aan het typen";
@ -808,6 +816,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Afbeeldingen kiezen";
"lng_game_tag" = "Spel";
"lng_context_view_profile" = "Profiel weergeven";
"lng_context_view_group" = "Groepsinformatie weergeven";

View File

@ -580,7 +580,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_action_pinned_media_contact" = "um contato";
"lng_action_pinned_media_location" = "uma localização";
"lng_action_pinned_media_sticker" = "um sticker";
"lng_action_game_score" = "{from} marcou {count:pontos|ponto|pontos} em {game}";
"lng_action_pinned_media_emoji_sticker" = "um {emoji} sticker";
"lng_action_pinned_media_game" = "o jogo «{game}»";
"lng_action_game_score" = "{from} marcou {count:# pontos|# ponto|# pontos} em {game}";
"lng_action_game_you_scored" = "Você marcou {count:# pontos|# ponto|# pontos} em {game}";
"lng_profile_migrate_reached" = "{count:_not_used_|# membro|# membros} limite alcançado";
"lng_profile_migrate_body" = "Para ir além desse limite, você pode converter seu grupo em um supergrupo.";
@ -774,6 +777,11 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_bot_groups_not_found" = "Nenhum grupo encontrado";
"lng_bot_sure_invite" = "Adicionar bot ao «{group}»?";
"lng_bot_already_in_group" = "O bot já é um membro do grupo.";
"lng_bot_choose_chat" = "Escolher Conversa";
"lng_bot_no_chats" = "Você não possui conversas";
"lng_bot_chats_not_found" = "Nenhuma conversa encontrada";
"lng_bot_sure_share_game" = "Compartilhar o jogo com {user}?";
"lng_bot_sure_share_game_group" = "Compartilhar o jogo com «{group}»?";
"lng_typing" = "escrevendo";
"lng_user_typing" = "{user} está escrevendo";
@ -808,6 +816,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
"lng_duration_played" = "{played} / {duration}";
"lng_date_and_duration" = "{date}, {duration}";
"lng_choose_images" = "Escolher imagens";
"lng_game_tag" = "Jogo";
"lng_context_view_profile" = "Ver perfil";
"lng_context_view_group" = "Ver info do grupo";

View File

@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,8,1
PRODUCTVERSION 0,10,8,1
FILEVERSION 0,10,8,3
PRODUCTVERSION 0,10,8,3
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -51,10 +51,10 @@ BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Telegram Messenger LLP"
VALUE "FileVersion", "0.10.8.1"
VALUE "FileVersion", "0.10.8.3"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.8.1"
VALUE "ProductVersion", "0.10.8.3"
END
END
BLOCK "VarFileInfo"

View File

@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,10,8,1
PRODUCTVERSION 0,10,8,1
FILEVERSION 0,10,8,3
PRODUCTVERSION 0,10,8,3
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.1"
VALUE "FileVersion", "0.10.8.3"
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
VALUE "ProductName", "Telegram Desktop"
VALUE "ProductVersion", "0.10.8.1"
VALUE "ProductVersion", "0.10.8.3"
END
END
BLOCK "VarFileInfo"

View File

@ -1196,22 +1196,20 @@ namespace {
ImagePtr image(const MTPPhotoSize &size) {
switch (size.type()) {
case mtpc_photoSize: {
const auto &d(size.c_photoSize());
auto &d = size.c_photoSize();
if (d.vlocation.type() == mtpc_fileLocation) {
const auto &l(d.vlocation.c_fileLocation());
auto &l = d.vlocation.c_fileLocation();
return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), d.vsize.v);
}
} break;
case mtpc_photoCachedSize: {
const auto &d(size.c_photoCachedSize());
auto &d = size.c_photoCachedSize();
if (d.vlocation.type() == mtpc_fileLocation) {
const auto &l(d.vlocation.c_fileLocation());
const auto &s(d.vbytes.c_string().v);
QByteArray bytes(s.data(), s.size());
auto &l = d.vlocation.c_fileLocation();
auto bytes = qba(d.vbytes);
return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, l.vdc_id.v, l.vvolume_id.v, l.vlocal_id.v, l.vsecret.v), bytes);
} else if (d.vlocation.type() == mtpc_fileLocationUnavailable) {
const string &s(d.vbytes.c_string().v);
QByteArray bytes(s.data(), s.size());
auto bytes = qba(d.vbytes);
return ImagePtr(StorageImageLocation(d.vw.v, d.vh.v, 0, 0, 0, 0), bytes);
}
} break;
@ -1429,12 +1427,12 @@ namespace {
char size = 0;
switch (i->type()) {
case mtpc_photoSize: {
const string &s(i->c_photoSize().vtype.c_string().v);
auto &s = i->c_photoSize().vtype.c_string().v;
if (s.size()) size = s[0];
} break;
case mtpc_photoCachedSize: {
const string &s(i->c_photoCachedSize().vtype.c_string().v);
auto &s = i->c_photoCachedSize().vtype.c_string().v;
if (s.size()) size = s[0];
} break;
}
@ -2069,22 +2067,28 @@ namespace {
cSetSavedPeers(SavedPeers());
cSetSavedPeersByTime(SavedPeersByTime());
cSetRecentInlineBots(RecentInlineBots());
for_const (PeerData *peer, peersData) {
for_const (auto peer, ::peersData) {
delete peer;
}
peersData.clear();
for_const (PhotoData *photo, ::photosData) {
::peersData.clear();
for_const (auto game, ::gamesData) {
delete game;
}
::gamesData.clear();
for_const (auto webpage, ::webPagesData) {
delete webpage;
}
::webPagesData.clear();
for_const (auto photo, ::photosData) {
delete photo;
}
::photosData.clear();
for_const (DocumentData *document, ::documentsData) {
for_const (auto document, ::documentsData) {
delete document;
}
::documentsData.clear();
for_const (WebPageData *webpage, webPagesData) {
delete webpage;
}
webPagesData.clear();
if (api()) api()->clearWebPageRequests();
cSetRecentStickers(RecentStickerPack());
Global::SetStickerSets(Stickers::Sets());

View File

@ -285,8 +285,8 @@ void MaxInviteBox::paintEvent(QPaintEvent *e) {
p.drawText(_invitationLink, _link, option);
if (!_goodTextLink.isEmpty() && a_goodOpacity.current() > 0) {
p.setOpacity(a_goodOpacity.current());
p.setPen(st::setGoodColor->p);
p.setFont(st::boxTextFont->f);
p.setPen(st::setGoodColor);
p.setFont(st::boxTextFont);
p.drawTextLeft(st::boxPadding.left(), height() - st::boxButtonPadding.bottom() - _close.height() + st::defaultBoxButton.textTop + st::defaultBoxButton.font->ascent - st::boxTextFont->ascent, width(), _goodTextLink);
p.setOpacity(1);
}

View File

@ -1508,8 +1508,8 @@ void StickersBox::paintEvent(QPaintEvent *e) {
void StickersBox::closePressed() {
if (!_disenableRequests.isEmpty()) {
for (QMap<mtpRequestId, NullType>::const_iterator i = _disenableRequests.cbegin(), e = _disenableRequests.cend(); i != e; ++i) {
MTP::cancel(i.key());
for_const (auto requestId, _disenableRequests) {
MTP::cancel(requestId);
}
_disenableRequests.clear();
Global::SetLastStickersUpdate(0);
@ -1607,7 +1607,7 @@ void StickersBox::onSave() {
if (!(it->flags & MTPDstickerSet::Flag::f_archived)) {
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
if (it->flags & MTPDstickerSet::Flag::f_official) {
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolTrue()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5));
it->flags |= MTPDstickerSet::Flag::f_archived;
auto index = Global::RefArchivedStickerSetsOrder().indexOf(it->id);
if (index < 0) {
@ -1615,7 +1615,7 @@ void StickersBox::onSave() {
writeArchived = true;
}
} else {
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
_disenableRequests.insert(MTP::send(MTPmessages_UninstallStickerSet(setId), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5));
int removeIndex = Global::StickerSetsOrder().indexOf(it->id);
if (removeIndex >= 0) Global::RefStickerSetsOrder().removeAt(removeIndex);
if (!(it->flags & MTPDstickerSet_ClientFlag::f_featured) && !(it->flags & MTPDstickerSet_ClientFlag::f_special)) {
@ -1645,7 +1645,7 @@ void StickersBox::onSave() {
if (it != sets.cend()) {
if ((it->flags & MTPDstickerSet::Flag::f_archived) && !disabled.contains(it->id)) {
MTPInputStickerSet setId = (it->id && it->access) ? MTP_inputStickerSetID(MTP_long(it->id), MTP_long(it->access)) : MTP_inputStickerSetShortName(MTP_string(it->shortName));
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5), NullType());
_disenableRequests.insert(MTP::send(MTPmessages_InstallStickerSet(setId, MTP_boolFalse()), rpcDone(&StickersBox::disenableDone), rpcFail(&StickersBox::disenableFail), 0, 5));
it->flags &= ~MTPDstickerSet::Flag::f_archived;
writeArchived = true;
}

View File

@ -186,7 +186,7 @@ private:
ChildWidget<internal::StickersInner> _inner;
ChildWidget<BoxButton> _save = { nullptr };
ChildWidget<BoxButton> _cancel = { nullptr };
QMap<mtpRequestId, NullType> _disenableRequests;
OrderedSet<mtpRequestId> _disenableRequests;
mtpRequestId _reorderRequest = 0;
ChildWidget<PlainShadow> _topShadow = { nullptr };
ChildWidget<ScrollableBoxShadow> _bottomShadow = { nullptr };

File diff suppressed because it is too large Load Diff

View File

@ -146,11 +146,9 @@ struct lambda_wrap_helper_move_impl<Lambda, std_::false_type, Return, Args...> :
}
static void construct_move_lambda_method(void *lambda, void *source) {
static_assert(alignof(JustLambda) <= alignof(void*), "Bad lambda alignment.");
#ifndef OS_MAC_OLD
auto space = sizeof(JustLambda);
auto aligned = std::align(alignof(JustLambda), space, lambda, space);
auto aligned = std_::align(alignof(JustLambda), space, lambda, space);
t_assert(aligned == lambda);
#endif // OS_MAC_OLD
auto source_lambda = static_cast<JustLambda*>(source);
new (lambda) JustLambda(static_cast<JustLambda&&>(*source_lambda));
}
@ -223,11 +221,9 @@ struct lambda_wrap_helper_copy_impl<Lambda, std_::false_type, Return, Args...> :
}
static void construct_copy_lambda_method(void *lambda, const void *source) {
static_assert(alignof(JustLambda) <= alignof(void*), "Bad lambda alignment.");
#ifndef OS_MAC_OLD
auto space = sizeof(JustLambda);
auto aligned = std::align(alignof(JustLambda), space, lambda, space);
auto aligned = std_::align(alignof(JustLambda), space, lambda, space);
t_assert(aligned == lambda);
#endif // OS_MAC_OLD
auto source_lambda = static_cast<const JustLambda*>(source);
new (lambda) JustLambda(static_cast<const JustLambda &>(*source_lambda));
}

View File

@ -0,0 +1,159 @@
/*
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 <QtCore/QMap>
// ordered set template based on QMap
template <typename T>
class OrderedSet {
struct NullType {
};
using Self = OrderedSet<T>;
using Impl = QMap<T, NullType>;
using IteratorImpl = typename Impl::iterator;
using ConstIteratorImpl = typename Impl::const_iterator;
Impl impl_;
public:
inline bool operator==(const Self &other) const { return impl_ == other.impl_; }
inline bool operator!=(const Self &other) const { return impl_ != other.impl_; }
inline int size() const { return impl_.size(); }
inline bool isEmpty() const { return impl_.isEmpty(); }
inline void detach() { return impl_.detach(); }
inline bool isDetached() const { return impl_.isDetached(); }
inline void clear() { return impl_.clear(); }
inline QList<T> values() const { return impl_.keys(); }
inline const T &first() const { return impl_.firstKey(); }
inline const T &last() const { return impl_.lastKey(); }
class const_iterator;
class iterator {
public:
typedef typename IteratorImpl::iterator_category iterator_category;
typedef typename IteratorImpl::difference_type difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
iterator() = default;
iterator(const iterator &other) = default;
iterator &operator=(const iterator &other) = default;
inline const T &operator*() const { return impl_.key(); }
inline const T *operator->() const { return &impl_.key(); }
inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
inline iterator &operator++() { ++impl_; return *this; }
inline iterator operator++(int) { return iterator(impl_++); }
inline iterator &operator--() { --impl_; return *this; }
inline iterator operator--(int) { return iterator(impl_--); }
inline iterator operator+(int j) const { return iterator(impl_ + j); }
inline iterator operator-(int j) const { return iterator(impl_ - j); }
inline iterator &operator+=(int j) { impl_ += j; return *this; }
inline iterator &operator-=(int j) { impl_ -= j; return *this; }
friend class const_iterator;
inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
private:
explicit iterator(const IteratorImpl &impl) : impl_(impl) {
}
IteratorImpl impl_;
friend class OrderedSet<T>;
};
friend class iterator;
class const_iterator {
public:
typedef typename IteratorImpl::iterator_category iterator_category;
typedef typename IteratorImpl::difference_type difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
const_iterator() = default;
const_iterator(const const_iterator &other) = default;
const_iterator &operator=(const const_iterator &other) = default;
const_iterator(const iterator &other) : impl_(other.impl_) {
}
const_iterator &operator=(const iterator &other) {
impl_ = other.impl_;
return *this;
}
inline const T &operator*() const { return impl_.key(); }
inline const T *operator->() const { return &impl_.key(); }
inline bool operator==(const const_iterator &other) const { return impl_ == other.impl_; }
inline bool operator!=(const const_iterator &other) const { return impl_ != other.impl_; }
inline const_iterator &operator++() { ++impl_; return *this; }
inline const_iterator operator++(int) { return const_iterator(impl_++); }
inline const_iterator &operator--() { --impl_; return *this; }
inline const_iterator operator--(int) { return const_iterator(impl_--); }
inline const_iterator operator+(int j) const { return const_iterator(impl_ + j); }
inline const_iterator operator-(int j) const { return const_iterator(impl_ - j); }
inline const_iterator &operator+=(int j) { impl_ += j; return *this; }
inline const_iterator &operator-=(int j) { impl_ -= j; return *this; }
friend class iterator;
inline bool operator==(const iterator &other) const { return impl_ == other.impl_; }
inline bool operator!=(const iterator &other) const { return impl_ != other.impl_; }
private:
explicit const_iterator(const ConstIteratorImpl &impl) : impl_(impl) {
}
ConstIteratorImpl impl_;
friend class OrderedSet<T>;
};
friend class const_iterator;
// STL style
inline iterator begin() { return iterator(impl_.begin()); }
inline const_iterator begin() const { return const_iterator(impl_.cbegin()); }
inline const_iterator constBegin() const { return const_iterator(impl_.cbegin()); }
inline const_iterator cbegin() const { return const_iterator(impl_.cbegin()); }
inline iterator end() { detach(); return iterator(impl_.end()); }
inline const_iterator end() const { return const_iterator(impl_.cend()); }
inline const_iterator constEnd() const { return const_iterator(impl_.cend()); }
inline const_iterator cend() const { return const_iterator(impl_.cend()); }
inline iterator erase(iterator it) { return iterator(impl_.erase(it.impl_)); }
inline iterator insert(const T &value) { return iterator(impl_.insert(value, NullType())); }
inline iterator insert(const_iterator pos, const T &value) { return iterator(impl_.insert(pos.impl_, value, NullType())); }
inline int remove(const T &value) { return impl_.remove(value); }
inline bool contains(const T &value) const { return impl_.contains(value); }
// more Qt
typedef iterator Iterator;
typedef const_iterator ConstIterator;
inline int count() const { return impl_.count(); }
inline iterator find(const T &value) { return iterator(impl_.find(value)); }
inline const_iterator find(const T &value) const { return const_iterator(impl_.constFind(value)); }
inline const_iterator constFind(const T &value) const { return const_iterator(impl_.constFind(value)); }
inline Self &unite(const Self &other) { impl_.unite(other.impl_); return *this; }
// STL compatibility
typedef typename Impl::difference_type difference_type;
typedef typename Impl::size_type size_type;
inline bool empty() const { return impl_.empty(); }
};

View File

@ -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
*/
#include "stdafx.h"
#include "core/runtime_composer.h"
struct RuntimeComposerMetadatasMap {
QMap<uint64, RuntimeComposerMetadata*> data;
~RuntimeComposerMetadatasMap() {
for_const (const RuntimeComposerMetadata *p, data) {
delete p;
}
}
};
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask) {
static RuntimeComposerMetadatasMap RuntimeComposerMetadatas;
static QMutex RuntimeComposerMetadatasMutex;
QMutexLocker lock(&RuntimeComposerMetadatasMutex);
auto i = RuntimeComposerMetadatas.data.constFind(mask);
if (i == RuntimeComposerMetadatas.data.cend()) {
RuntimeComposerMetadata *meta = new RuntimeComposerMetadata(mask);
t_assert(meta != nullptr);
i = RuntimeComposerMetadatas.data.insert(mask, meta);
}
return i.value();
}
const RuntimeComposerMetadata *RuntimeComposer::ZeroRuntimeComposerMetadata = GetRuntimeComposerMetadata(0);
RuntimeComponentWrapStruct RuntimeComponentWraps[64];
QAtomicInt RuntimeComponentIndexLast;

View File

@ -0,0 +1,257 @@
/*
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
class RuntimeComposer;
typedef void(*RuntimeComponentConstruct)(void *location, RuntimeComposer *composer);
typedef void(*RuntimeComponentDestruct)(void *location);
typedef void(*RuntimeComponentMove)(void *location, void *waslocation);
struct RuntimeComponentWrapStruct {
// don't init any fields, because it is only created in
// global scope, so it will be filled by zeros from the start
RuntimeComponentWrapStruct() = default;
RuntimeComponentWrapStruct(std::size_t size, std::size_t align, RuntimeComponentConstruct construct, RuntimeComponentDestruct destruct, RuntimeComponentMove move)
: Size(size)
, Align(align)
, Construct(construct)
, Destruct(destruct)
, Move(move) {
}
std::size_t Size;
std::size_t Align;
RuntimeComponentConstruct Construct;
RuntimeComponentDestruct Destruct;
RuntimeComponentMove Move;
};
template <int Value, int Denominator>
struct CeilDivideMinimumOne {
static constexpr int Result = ((Value / Denominator) + ((!Value || (Value % Denominator)) ? 1 : 0));
};
extern RuntimeComponentWrapStruct RuntimeComponentWraps[64];
extern QAtomicInt RuntimeComponentIndexLast;
template <typename Type>
struct RuntimeComponent {
RuntimeComponent() {
static_assert(alignof(Type) <= alignof(SmallestSizeType), "Components should align to a pointer!");
}
RuntimeComponent(const RuntimeComponent &other) = delete;
RuntimeComponent &operator=(const RuntimeComponent &other) = delete;
RuntimeComponent(RuntimeComponent &&other) = delete;
RuntimeComponent &operator=(RuntimeComponent &&other) = default;
static int Index() {
static QAtomicInt _index(0);
if (int index = _index.loadAcquire()) {
return index - 1;
}
while (true) {
int last = RuntimeComponentIndexLast.loadAcquire();
if (RuntimeComponentIndexLast.testAndSetOrdered(last, last + 1)) {
t_assert(last < 64);
if (_index.testAndSetOrdered(0, last + 1)) {
RuntimeComponentWraps[last] = RuntimeComponentWrapStruct(
CeilDivideMinimumOne<sizeof(Type), sizeof(SmallestSizeType)>::Result * sizeof(SmallestSizeType),
alignof(Type),
Type::RuntimeComponentConstruct,
Type::RuntimeComponentDestruct,
Type::RuntimeComponentMove);
}
break;
}
}
return _index.loadAcquire() - 1;
}
static uint64 Bit() {
return (1ULL << Index());
}
protected:
using SmallestSizeType = void*;
static void RuntimeComponentConstruct(void *location, RuntimeComposer *composer) {
new (location) Type();
}
static void RuntimeComponentDestruct(void *location) {
((Type*)location)->~Type();
}
static void RuntimeComponentMove(void *location, void *waslocation) {
*(Type*)location = std_::move(*(Type*)waslocation);
}
};
class RuntimeComposerMetadata {
public:
RuntimeComposerMetadata(uint64 mask) : size(0), last(64), _mask(mask) {
for (int i = 0; i < 64; ++i) {
uint64 m = (1ULL << i);
if (_mask & m) {
int s = RuntimeComponentWraps[i].Size;
if (s) {
offsets[i] = size;
size += s;
} else {
offsets[i] = -1;
}
} else if (_mask < m) {
last = i;
for (; i < 64; ++i) {
offsets[i] = -1;
}
} else {
offsets[i] = -1;
}
}
}
int size, last;
int offsets[64];
bool equals(uint64 mask) const {
return _mask == mask;
}
uint64 maskadd(uint64 mask) const {
return _mask | mask;
}
uint64 maskremove(uint64 mask) const {
return _mask & (~mask);
}
private:
uint64 _mask;
};
const RuntimeComposerMetadata *GetRuntimeComposerMetadata(uint64 mask);
class RuntimeComposer {
public:
RuntimeComposer(uint64 mask = 0) : _data(zerodata()) {
if (mask) {
const RuntimeComposerMetadata *meta = GetRuntimeComposerMetadata(mask);
int size = sizeof(meta) + meta->size;
auto data = operator new(size);
t_assert(data != nullptr);
_data = data;
_meta() = meta;
for (int i = 0; i < meta->last; ++i) {
int offset = meta->offsets[i];
if (offset >= 0) {
try {
auto constructAt = _dataptrunsafe(offset);
auto space = RuntimeComponentWraps[i].Size;
auto alignedAt = std_::align(RuntimeComponentWraps[i].Align, space, constructAt, space);
t_assert(alignedAt == constructAt);
RuntimeComponentWraps[i].Construct(constructAt, this);
} catch (...) {
while (i > 0) {
--i;
offset = meta->offsets[--i];
if (offset >= 0) {
RuntimeComponentWraps[i].Destruct(_dataptrunsafe(offset));
}
}
throw;
}
}
}
}
}
RuntimeComposer(const RuntimeComposer &other) = delete;
RuntimeComposer &operator=(const RuntimeComposer &other) = delete;
~RuntimeComposer() {
if (_data != zerodata()) {
auto meta = _meta();
for (int i = 0; i < meta->last; ++i) {
int offset = meta->offsets[i];
if (offset >= 0) {
RuntimeComponentWraps[i].Destruct(_dataptrunsafe(offset));
}
}
operator delete(_data);
}
}
template <typename Type>
bool Has() const {
return (_meta()->offsets[Type::Index()] >= 0);
}
template <typename Type>
Type *Get() {
return static_cast<Type*>(_dataptr(_meta()->offsets[Type::Index()]));
}
template <typename Type>
const Type *Get() const {
return static_cast<const Type*>(_dataptr(_meta()->offsets[Type::Index()]));
}
protected:
void UpdateComponents(uint64 mask = 0) {
if (!_meta()->equals(mask)) {
RuntimeComposer tmp(mask);
tmp.swap(*this);
if (_data != zerodata() && tmp._data != zerodata()) {
auto meta = _meta(), wasmeta = tmp._meta();
for (int i = 0; i < meta->last; ++i) {
int offset = meta->offsets[i], wasoffset = wasmeta->offsets[i];
if (offset >= 0 && wasoffset >= 0) {
RuntimeComponentWraps[i].Move(_dataptrunsafe(offset), tmp._dataptrunsafe(wasoffset));
}
}
}
}
}
void AddComponents(uint64 mask = 0) {
UpdateComponents(_meta()->maskadd(mask));
}
void RemoveComponents(uint64 mask = 0) {
UpdateComponents(_meta()->maskremove(mask));
}
private:
static const RuntimeComposerMetadata *ZeroRuntimeComposerMetadata;
static void *zerodata() {
return &ZeroRuntimeComposerMetadata;
}
void *_dataptrunsafe(int skip) const {
return (char*)_data + sizeof(_meta()) + skip;
}
void *_dataptr(int skip) const {
return (skip >= 0) ? _dataptrunsafe(skip) : 0;
}
const RuntimeComposerMetadata *&_meta() const {
return *static_cast<const RuntimeComposerMetadata**>(_data);
}
void *_data;
void swap(RuntimeComposer &other) {
std::swap(_data, other._data);
}
};

View File

@ -0,0 +1,282 @@
/*
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 <stdint.h>
// we copy some parts of C++11/14/17 std:: library, because on OS X 10.6+
// version we can use C++11/14/17, but we can not use its library :(
namespace std_ {
using nullptr_t = decltype(nullptr);
template <typename T, T V>
struct integral_constant {
static constexpr T value = V;
using value_type = T;
using type = integral_constant<T, V>;
constexpr operator value_type() const noexcept {
return (value);
}
constexpr value_type operator()() const noexcept {
return (value);
}
};
using true_type = integral_constant<bool, true>;
using false_type = integral_constant<bool, false>;
template <typename T>
struct remove_reference {
using type = T;
};
template <typename T>
struct remove_reference<T&> {
using type = T;
};
template <typename T>
struct remove_reference<T&&> {
using type = T;
};
template <typename T>
struct is_lvalue_reference : false_type {
};
template <typename T>
struct is_lvalue_reference<T&> : true_type {
};
template <typename T>
struct is_rvalue_reference : false_type {
};
template <typename T>
struct is_rvalue_reference<T&&> : true_type {
};
template <typename T>
inline constexpr T &&forward(typename remove_reference<T>::type &value) noexcept {
return static_cast<T&&>(value);
}
template <typename T>
inline constexpr T &&forward(typename remove_reference<T>::type &&value) noexcept {
static_assert(!is_lvalue_reference<T>::value, "bad forward call");
return static_cast<T&&>(value);
}
template <typename T>
inline constexpr typename remove_reference<T>::type &&move(T &&value) noexcept {
return static_cast<typename remove_reference<T>::type&&>(value);
}
template <typename T>
void swap(T &a, T &b) {
T tmp = move(a);
a = move(b);
b = move(tmp);
}
template <typename T>
struct remove_const {
using type = T;
};
template <typename T>
struct remove_const<const T> {
using type = T;
};
template <typename T>
struct remove_volatile {
using type = T;
};
template <typename T>
struct remove_volatile<volatile T> {
using type = T;
};
template <typename T>
using decay_simple_t = typename remove_const<typename remove_volatile<typename remove_reference<T>::type>::type>::type;
template <typename T1, typename T2>
struct is_same : false_type {
};
template <typename T>
struct is_same<T, T> : true_type {
};
template <bool, typename T = void>
struct enable_if {
};
template <typename T>
struct enable_if<true, T> {
using type = T;
};
template <bool Test, typename T = void>
using enable_if_t = typename enable_if<Test, T>::type;
template <typename T>
struct add_const {
using type = const T;
};
template <typename T>
using add_const_t = typename add_const<T>::type;
template <typename T>
constexpr add_const_t<T> &as_const(T& t) noexcept {
return t;
}
template <typename T>
void as_const(const T&&) = delete;
// This is not full unique_ptr, but at least with std interface.
template <typename T>
class unique_ptr {
public:
constexpr unique_ptr() noexcept = default;
unique_ptr(const unique_ptr<T> &) = delete;
unique_ptr<T> &operator=(const unique_ptr<T> &) = delete;
constexpr unique_ptr(std_::nullptr_t) {
}
unique_ptr<T> &operator=(std_::nullptr_t) noexcept {
reset();
return (*this);
}
explicit unique_ptr(T *p) noexcept : _p(p) {
}
template <typename U>
unique_ptr(unique_ptr<U> &&other) noexcept : _p(other.release()) {
}
template <typename U>
unique_ptr<T> &operator=(unique_ptr<U> &&other) noexcept {
reset(other.release());
return (*this);
}
unique_ptr<T> &operator=(unique_ptr<T> &&other) noexcept {
if (this != &other) {
reset(other.release());
}
return (*this);
}
void swap(unique_ptr<T> &other) noexcept {
std::swap(_p, other._p);
}
~unique_ptr() noexcept {
delete _p;
}
T &operator*() const {
return (*get());
}
T *operator->() const noexcept {
return get();
}
T *get() const noexcept {
return _p;
}
explicit operator bool() const noexcept {
return get() != nullptr;
}
T *release() noexcept {
auto old = _p;
_p = nullptr;
return old;
}
void reset(T *p = nullptr) noexcept {
auto old = _p;
_p = p;
if (old) {
delete old;
}
}
private:
T *_p = nullptr;
};
template <typename T, typename... Args>
inline unique_ptr<T> make_unique(Args&&... args) {
return unique_ptr<T>(new T(forward<Args>(args)...));
}
template <typename T>
inline bool operator==(const unique_ptr<T> &a, std_::nullptr_t) noexcept {
return !a;
}
template <typename T>
inline bool operator==(std_::nullptr_t, const unique_ptr<T> &b) noexcept {
return !b;
}
template <typename T>
inline bool operator!=(const unique_ptr<T> &a, std_::nullptr_t b) noexcept {
return !(a == b);
}
template <typename T>
inline bool operator!=(std_::nullptr_t a, const unique_ptr<T> &b) noexcept {
return !(a == b);
}
using _yes = char(&)[1];
using _no = char(&)[2];
template <typename Base, typename Derived>
struct _host {
operator Base*() const;
operator Derived*();
};
template <typename Base, typename Derived>
struct is_base_of {
template <typename T>
static _yes check(Derived*, T);
static _no check(Base*, int);
static constexpr bool value = sizeof(check(_host<Base, Derived>(), int())) == sizeof(_yes);
};
inline void *align(size_t alignment, size_t size, void*& ptr, size_t& space) noexcept {
#ifndef OS_MAC_OLD
using std::uintptr_t;
#endif // OS_MAC_OLD
auto p = reinterpret_cast<uintptr_t>(ptr);
auto a = (p - 1u + alignment) & -alignment;
auto d = a - p;
if ((size + d) > space) {
return nullptr;
}
space -= d;
return ptr = reinterpret_cast<void*>(a);
}
} // namespace std_

View File

@ -19,8 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "basic_types.h"
#include "core/utils.h"
#include <openssl/crypto.h>
#include <openssl/sha.h>
@ -1020,33 +1019,3 @@ MimeType mimeTypeForData(const QByteArray &data) {
}
return MimeType(QMimeDatabase().mimeTypeForData(data));
}
struct ComposerMetadatasMap {
QMap<uint64, ComposerMetadata*> data;
~ComposerMetadatasMap() {
for_const (const ComposerMetadata *p, data) {
delete p;
}
}
};
const ComposerMetadata *GetComposerMetadata(uint64 mask) {
static ComposerMetadatasMap ComposerMetadatas;
static QMutex ComposerMetadatasMutex;
QMutexLocker lock(&ComposerMetadatasMutex);
auto i = ComposerMetadatas.data.constFind(mask);
if (i == ComposerMetadatas.data.cend()) {
ComposerMetadata *meta = new ComposerMetadata(mask);
t_assert(meta != nullptr);
i = ComposerMetadatas.data.insert(mask, meta);
}
return i.value();
}
const ComposerMetadata *Composer::ZeroComposerMetadata = GetComposerMetadata(0);
ComponentWrapStruct ComponentWraps[64];
QAtomicInt ComponentIndexLast;

View File

@ -0,0 +1,581 @@
/*
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"
template <typename T, size_t N>
inline constexpr size_t arraysize(T(&ArrahSizeHelper)[N]) {
return N;
}
template <typename T>
void deleteAndMark(T *&link) {
delete link;
link = reinterpret_cast<T*>(0x00000BAD);
}
template <typename T>
T *getPointerAndReset(T *&ptr) {
T *result = nullptr;
qSwap(result, ptr);
return result;
}
template <typename Enum>
inline QFlags<Enum> qFlags(Enum v) {
return QFlags<Enum>(v);
}
static const int32 ScrollMax = INT_MAX;
extern uint64 _SharedMemoryLocation[];
template <typename T, unsigned int N>
T *SharedMemoryLocation() {
static_assert(N < 4, "Only 4 shared memory locations!");
return reinterpret_cast<T*>(_SharedMemoryLocation + N);
}
// see https://github.com/boostcon/cppnow_presentations_2012/blob/master/wed/schurr_cpp11_tools_for_class_authors.pdf
class str_const { // constexpr string
public:
template<std::size_t N>
constexpr str_const(const char(&a)[N]) : _str(a), _size(N - 1) {
}
constexpr char operator[](std::size_t n) const {
return (n < _size) ? _str[n] :
#ifndef OS_MAC_OLD
throw std::out_of_range("");
#else // OS_MAC_OLD
throw std::exception();
#endif // OS_MAC_OLD
}
constexpr std::size_t size() const { return _size; }
const char *c_str() const { return _str; }
private:
const char* const _str;
const std::size_t _size;
};
inline QString str_const_toString(const str_const &str) {
return QString::fromUtf8(str.c_str(), str.size());
}
template <typename T>
inline void accumulate_max(T &a, const T &b) { if (a < b) a = b; }
template <typename T>
inline void accumulate_min(T &a, const T &b) { if (a > b) a = b; }
template <typename T>
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) {
QString info(qsl("%1 %2:%3").arg(message).arg(file).arg(line));
LOG(("Assertion Failed! %1 %2:%3").arg(info));
SignalHandlers::setCrashAnnotation("Assertion", info);
*t_assert_nullptr = 0;
}
#define t_assert_full(condition, message, file, line) ((!(condition)) ? t_assert_fail(message, file, line) : t_noop())
#define t_assert_c(condition, comment) t_assert_full(condition, "\"" #condition "\" (" comment ")", __FILE__, __LINE__)
#define t_assert(condition) t_assert_full(condition, "\"" #condition "\"", __FILE__, __LINE__)
class Exception : public std::exception {
public:
Exception(const QString &msg, bool isFatal = true) : _fatal(isFatal), _msg(msg.toUtf8()) {
LOG(("Exception: %1").arg(msg));
}
bool fatal() const {
return _fatal;
}
virtual const char *what() const throw() {
return _msg.constData();
}
virtual ~Exception() throw() {
}
private:
bool _fatal;
QByteArray _msg;
};
class MTPint;
using TimeId = int32;
TimeId myunixtime();
void unixtimeInit();
void unixtimeSet(TimeId servertime, bool force = false);
TimeId unixtime();
TimeId fromServerTime(const MTPint &serverTime);
void toServerTime(const TimeId &clientTime, MTPint &outServerTime);
uint64 msgid();
int32 reqid();
inline QDateTime date(int32 time = -1) {
QDateTime result;
if (time >= 0) result.setTime_t(time);
return result;
}
inline QDateTime dateFromServerTime(const MTPint &time) {
return date(fromServerTime(time));
}
inline QDateTime date(const MTPint &time) {
return dateFromServerTime(time);
}
QDateTime dateFromServerTime(TimeId time);
inline void mylocaltime(struct tm * _Tm, const time_t * _Time) {
#ifdef Q_OS_WIN
localtime_s(_Tm, _Time);
#else
localtime_r(_Time, _Tm);
#endif
}
namespace ThirdParty {
void start();
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:
HashMd5(const void *input = 0, uint32 length = 0);
void feed(const void *input, uint32 length);
int32 *result();
private:
void init();
void finalize();
void transform(const uchar *block);
bool _finalized;
uchar _buffer[_md5_block_size];
uint32 _count[2];
uint32 _state[4];
uchar _digest[16];
};
int32 hashCrc32(const void *data, uint32 len);
int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest
int32 *hashSha256(const void *data, uint32 len, void *dest); // dest - ptr to 32 bytes, returns (int32*)dest
int32 *hashMd5(const void *data, uint32 len, void *dest); // dest = ptr to 16 bytes, returns (int32*)dest
char *hashMd5Hex(const int32 *hashmd5, void *dest); // dest = ptr to 32 bytes, returns (char*)dest
inline char *hashMd5Hex(const void *data, uint32 len, void *dest) { // dest = ptr to 32 bytes, returns (char*)dest
return hashMd5Hex(HashMd5(data, len).result(), dest);
}
// good random (using openssl implementation)
void memset_rand(void *data, uint32 len);
template <typename T>
T rand_value() {
T result;
memset_rand(&result, sizeof(result));
return result;
}
inline void memset_rand_bad(void *data, uint32 len) {
for (uchar *i = reinterpret_cast<uchar*>(data), *e = i + len; i != e; ++i) {
*i = uchar(rand() & 0xFF);
}
}
template <typename T>
inline void memsetrnd_bad(T &value) {
memset_rand_bad(&value, sizeof(value));
}
class ReadLockerAttempt {
public:
ReadLockerAttempt(QReadWriteLock *_lock) : success(_lock->tryLockForRead()), lock(_lock) {
}
~ReadLockerAttempt() {
if (success) {
lock->unlock();
}
}
operator bool() const {
return success;
}
private:
bool success;
QReadWriteLock *lock;
};
inline QString fromUtf8Safe(const char *str, int32 size = -1) {
if (!str || !size) return QString();
if (size < 0) size = int32(strlen(str));
QString result(QString::fromUtf8(str, size));
QByteArray back = result.toUtf8();
if (back.size() != size || memcmp(back.constData(), str, size)) return QString::fromLocal8Bit(str, size);
return result;
}
inline QString fromUtf8Safe(const QByteArray &str) {
return fromUtf8Safe(str.constData(), str.size());
}
static const QRegularExpression::PatternOptions reMultiline(QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption);
template <typename T>
inline T snap(const T &v, const T &_min, const T &_max) {
return (v < _min) ? _min : ((v > _max) ? _max : v);
}
template <typename T>
class ManagedPtr {
public:
ManagedPtr() : ptr(0) {
}
ManagedPtr(T *p) : ptr(p) {
}
T *operator->() const {
return ptr;
}
T *v() const {
return ptr;
}
protected:
T *ptr;
typedef ManagedPtr<T> Parent;
};
QString translitRusEng(const QString &rus);
QString rusKeyboardLayoutSwitch(const QString &from);
enum DBISendKey {
dbiskEnter = 0,
dbiskCtrlEnter = 1,
};
enum DBINotifyView {
dbinvShowPreview = 0,
dbinvShowName = 1,
dbinvShowNothing = 2,
};
enum DBIWorkMode {
dbiwmWindowAndTray = 0,
dbiwmTrayOnly = 1,
dbiwmWindowOnly = 2,
};
enum DBIConnectionType {
dbictAuto = 0,
dbictHttpAuto = 1, // not used
dbictHttpProxy = 2,
dbictTcpProxy = 3,
};
enum DBIDefaultAttach {
dbidaDocument = 0,
dbidaPhoto = 1,
};
struct ProxyData {
QString host;
uint32 port = 0;
QString user, password;
};
enum DBIScale {
dbisAuto = 0,
dbisOne = 1,
dbisOneAndQuarter = 2,
dbisOneAndHalf = 3,
dbisTwo = 4,
dbisScaleCount = 5,
};
static const int MatrixRowShift = 40000;
enum DBIEmojiTab {
dbietRecent = -1,
dbietPeople = 0,
dbietNature = 1,
dbietFood = 2,
dbietActivity = 3,
dbietTravel = 4,
dbietObjects = 5,
dbietSymbols = 6,
dbietStickers = 666,
};
static const int emojiTabCount = 8;
inline DBIEmojiTab emojiTabAtIndex(int index) {
return (index < 0 || index >= emojiTabCount) ? dbietRecent : DBIEmojiTab(index - 1);
}
enum DBIPlatform {
dbipWindows = 0,
dbipMac = 1,
dbipLinux64 = 2,
dbipLinux32 = 3,
dbipMacOld = 4,
};
enum DBIPeerReportSpamStatus {
dbiprsNoButton = 0, // hidden, but not in the cloud settings yet
dbiprsUnknown = 1, // contacts not loaded yet
dbiprsShowButton = 2, // show report spam button, each show peer request setting from cloud
dbiprsReportSent = 3, // report sent, but the report spam panel is not hidden yet
dbiprsHidden = 4, // hidden in the cloud or not needed (bots, contacts, etc), no more requests
dbiprsRequesting = 5, // requesting the cloud setting right now
};
inline QString strMakeFromLetters(const uint32 *letters, int32 len) {
QString result;
result.reserve(len);
for (int32 i = 0; i < len; ++i) {
result.push_back(QChar((((letters[i] >> 16) & 0xFF) << 8) | (letters[i] & 0xFF)));
}
return result;
}
class MimeType {
public:
enum TypeEnum {
Unknown,
WebP,
};
MimeType(const QMimeType &type) : _typeStruct(type), _type(Unknown) {
}
MimeType(TypeEnum type) : _type(type) {
}
QStringList globPatterns() const;
QString filterString() const;
QString name() const;
private:
QMimeType _typeStruct;
TypeEnum _type;
};
MimeType mimeTypeForName(const QString &mime);
MimeType mimeTypeForFile(const QFileInfo &file);
MimeType mimeTypeForData(const QByteArray &data);
#include <cmath>
inline int rowscount(int fullCount, int countPerRow) {
return (fullCount + countPerRow - 1) / countPerRow;
}
inline int floorclamp(int value, int step, int lowest, int highest) {
return qMin(qMax(value / step, lowest), highest);
}
inline int floorclamp(float64 value, int step, int lowest, int highest) {
return qMin(qMax(static_cast<int>(std::floor(value / step)), lowest), highest);
}
inline int ceilclamp(int value, int step, int lowest, int highest) {
return qMax(qMin((value + step - 1) / step, highest), lowest);
}
inline int ceilclamp(float64 value, int32 step, int32 lowest, int32 highest) {
return qMax(qMin(static_cast<int>(std::ceil(value / step)), highest), lowest);
}
enum ForwardWhatMessages {
ForwardSelectedMessages,
ForwardContextMessage,
ForwardPressedMessage,
ForwardPressedLinkMessage
};
enum ShowLayerOption {
CloseOtherLayers = 0x00,
KeepOtherLayers = 0x01,
ShowAfterOtherLayers = 0x03,
AnimatedShowLayer = 0x00,
ForceFastShowLayer = 0x04,
};
Q_DECLARE_FLAGS(ShowLayerOptions, ShowLayerOption);
Q_DECLARE_OPERATORS_FOR_FLAGS(ShowLayerOptions);
static int32 FullArcLength = 360 * 16;
static int32 QuarterArcLength = (FullArcLength / 4);
static int32 MinArcLength = (FullArcLength / 360);
static int32 AlmostFullArcLength = (FullArcLength - MinArcLength);
template <typename T, typename... Args>
inline QSharedPointer<T> MakeShared(Args&&... args) {
return QSharedPointer<T>(new T(std_::forward<Args>(args)...));
}
// This pointer is used for global non-POD variables that are allocated
// on demand by createIfNull(lambda) and are never automatically freed.
template <typename T>
class NeverFreedPointer {
public:
NeverFreedPointer() = default;
NeverFreedPointer(const NeverFreedPointer<T> &other) = delete;
NeverFreedPointer &operator=(const NeverFreedPointer<T> &other) = delete;
template <typename U>
void createIfNull(U creator) {
if (isNull()) {
reset(creator());
}
}
template <typename... Args>
void makeIfNull(Args&&... args) {
if (isNull()) {
reset(new T(std_::forward<Args>(args)...));
}
};
T *data() const {
return _p;
}
T *release() {
return getPointerAndReset(_p);
}
void reset(T *p = nullptr) {
delete _p;
_p = p;
}
bool isNull() const {
return data() == nullptr;
}
void clear() {
reset();
}
T *operator->() const {
return data();
}
T &operator*() const {
t_assert(!isNull());
return *data();
}
explicit operator bool() const {
return !isNull();
}
private:
T *_p;
};
// This pointer is used for static non-POD variables that are allocated
// on first use by constructor and are never automatically freed.
template <typename T>
class StaticNeverFreedPointer {
public:
explicit StaticNeverFreedPointer(T *p) : _p(p) {
}
StaticNeverFreedPointer(const StaticNeverFreedPointer<T> &other) = delete;
StaticNeverFreedPointer &operator=(const StaticNeverFreedPointer<T> &other) = delete;
T *data() const {
return _p;
}
T *release() {
return getPointerAndReset(_p);
}
void reset(T *p = nullptr) {
delete _p;
_p = p;
}
bool isNull() const {
return data() == nullptr;
}
void clear() {
reset();
}
T *operator->() const {
return data();
}
T &operator*() const {
t_assert(!isNull());
return *data();
}
explicit operator bool() const {
return !isNull();
}
private:
T *_p = nullptr;
};

View File

@ -20,9 +20,9 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "core/basic_types.h"
#include "core/utils.h"
#define BETA_VERSION_MACRO (10008001ULL)
#define BETA_VERSION_MACRO (10008003ULL)
constexpr int AppVersion = 10008;
constexpr str_const AppVersionStr = "0.10.8";

View File

@ -945,7 +945,7 @@ bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMe
}
if (!adding) return false;
overviewIds[type].insert(msgId, NullType());
overviewIds[type].insert(msgId);
switch (method) {
case AddToOverviewNew:
case AddToOverviewBack: overview[type].push_back(msgId); break;
@ -963,11 +963,11 @@ bool History::addToOverview(MediaOverviewType type, MsgId msgId, AddToOverviewMe
void History::eraseFromOverview(MediaOverviewType type, MsgId msgId) {
if (overviewIds[type].isEmpty()) return;
History::MediaOverviewIds::iterator i = overviewIds[type].find(msgId);
auto i = overviewIds[type].find(msgId);
if (i == overviewIds[type].cend()) return;
overviewIds[type].erase(i);
for (History::MediaOverview::iterator i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
for (auto i = overview[type].begin(), e = overview[type].end(); i != e; ++i) {
if ((*i) == msgId) {
overview[type].erase(i);
if (overviewCountData[type] > 0) {
@ -2011,8 +2011,8 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
if (!onlyCounts && v->isEmpty()) {
overviewCountData[overviewIndex] = 0;
} else if (overviewCountData[overviewIndex] > 0) {
for (History::MediaOverviewIds::const_iterator i = overviewIds[overviewIndex].cbegin(), e = overviewIds[overviewIndex].cend(); i != e; ++i) {
if (i.key() < 0) {
for_const (auto msgId, overviewIds[overviewIndex]) {
if (msgId < 0) {
++overviewCountData[overviewIndex];
} else {
break;
@ -2023,7 +2023,7 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
for (QVector<MTPMessage>::const_iterator i = v->cbegin(), e = v->cend(); i != e; ++i) {
HistoryItem *item = App::histories().addNewMessage(*i, NewMessageExisting);
if (item && overviewIds[overviewIndex].constFind(item->id) == overviewIds[overviewIndex].cend()) {
overviewIds[overviewIndex].insert(item->id, NullType());
overviewIds[overviewIndex].insert(item->id);
overview[overviewIndex].push_front(item->id);
}
}
@ -2031,12 +2031,12 @@ void History::overviewSliceDone(int32 overviewIndex, const MTPmessages_Messages
void History::changeMsgId(MsgId oldId, MsgId newId) {
for (int32 i = 0; i < OverviewCount; ++i) {
History::MediaOverviewIds::iterator j = overviewIds[i].find(oldId);
auto j = overviewIds[i].find(oldId);
if (j != overviewIds[i].cend()) {
overviewIds[i].erase(j);
int32 index = overview[i].indexOf(oldId);
if (overviewIds[i].constFind(newId) == overviewIds[i].cend()) {
overviewIds[i].insert(newId, NullType());
overviewIds[i].insert(newId);
if (index >= 0) {
overview[i][index] = newId;
} else {

View File

@ -431,9 +431,9 @@ public:
return result;
}
MsgId overviewMinId(int32 overviewIndex) const {
for (MediaOverviewIds::const_iterator i = overviewIds[overviewIndex].cbegin(), e = overviewIds[overviewIndex].cend(); i != e; ++i) {
if (i.key() > 0) {
return i.key();
for_const (auto msgId, overviewIds[overviewIndex]) {
if (msgId > 0) {
return msgId;
}
}
return 0;
@ -525,7 +525,7 @@ private:
}
uint64 _sortKeyInChatList = 0; // like ((unixtime) << 32) | (incremented counter)
typedef QMap<MsgId, NullType> MediaOverviewIds;
using MediaOverviewIds = OrderedSet<MsgId>;
MediaOverviewIds overviewIds[OverviewCount];
int32 overviewCountData[OverviewCount]; // -1 - not loaded, 0 - all loaded, > 0 - count, but not all loaded

View File

@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "core/runtime_composer.h"
class HistoryElement {
public:
HistoryElement() = default;
@ -95,7 +97,7 @@ enum HistoryItemType {
HistoryItemJoined
};
struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
struct HistoryMessageVia : public RuntimeComponent<HistoryMessageVia> {
void create(int32 userId);
void resize(int32 availw) const;
@ -106,20 +108,20 @@ struct HistoryMessageVia : public BaseComponent<HistoryMessageVia> {
ClickHandlerPtr _lnk;
};
struct HistoryMessageViews : public BaseComponent<HistoryMessageViews> {
struct HistoryMessageViews : public RuntimeComponent<HistoryMessageViews> {
QString _viewsText;
int _views = 0;
int _viewsWidth = 0;
};
struct HistoryMessageSigned : public BaseComponent<HistoryMessageSigned> {
struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned> {
void create(UserData *from, const QDateTime &date);
int maxWidth() const;
Text _signature;
};
struct HistoryMessageEdited : public BaseComponent<HistoryMessageEdited> {
struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited> {
void create(const QDateTime &editDate, const QDateTime &date);
int maxWidth() const;
@ -127,7 +129,7 @@ struct HistoryMessageEdited : public BaseComponent<HistoryMessageEdited> {
Text _edited;
};
struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded> {
void create(const HistoryMessageVia *via) const;
PeerData *_authorOriginal = nullptr;
@ -136,7 +138,7 @@ struct HistoryMessageForwarded : public BaseComponent<HistoryMessageForwarded> {
mutable Text _text = { 1 };
};
struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply> {
HistoryMessageReply &operator=(HistoryMessageReply &&other) {
replyToMsgId = other.replyToMsgId;
std::swap(replyToMsg, other.replyToMsg);
@ -191,7 +193,7 @@ struct HistoryMessageReply : public BaseComponent<HistoryMessageReply> {
Q_DECLARE_OPERATORS_FOR_FLAGS(HistoryMessageReply::PaintFlags);
class ReplyKeyboard;
struct HistoryMessageReplyMarkup : public BaseComponent<HistoryMessageReplyMarkup> {
struct HistoryMessageReplyMarkup : public RuntimeComponent<HistoryMessageReplyMarkup> {
HistoryMessageReplyMarkup() = default;
HistoryMessageReplyMarkup(MTPDreplyKeyboardMarkup::Flags f) : flags(f) {
}
@ -362,7 +364,7 @@ private:
// any HistoryItem can have this Interface for
// displaying the day mark above the message
struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
struct HistoryMessageDate : public RuntimeComponent<HistoryMessageDate> {
void init(const QDateTime &date);
int height() const;
@ -374,7 +376,7 @@ struct HistoryMessageDate : public BaseComponent<HistoryMessageDate> {
// any HistoryItem can have this Interface for
// displaying the unread messages bar above the message
struct HistoryMessageUnreadBar : public BaseComponent<HistoryMessageUnreadBar> {
struct HistoryMessageUnreadBar : public RuntimeComponent<HistoryMessageUnreadBar> {
void init(int count);
static int height();
@ -439,7 +441,7 @@ namespace internal {
} // namespace internal
class HistoryItem : public HistoryElement, public Composer, public ClickHandlerHost {
class HistoryItem : public HistoryElement, public RuntimeComposer, public ClickHandlerHost {
public:
int resizeGetHeight(int width) {
if (_flags & MTPDmessage_ClientFlag::f_pending_init_dimensions) {

View File

@ -527,13 +527,13 @@ void HistoryPhoto::updateSentMedia(const MTPMessageMedia &media) {
const MTPFileLocation *loc = 0;
switch (sizes.at(i).type()) {
case mtpc_photoSize: {
const string &s(sizes.at(i).c_photoSize().vtype.c_string().v);
auto &s = sizes.at(i).c_photoSize().vtype.c_string().v;
loc = &sizes.at(i).c_photoSize().vlocation;
if (s.size()) size = s[0];
} break;
case mtpc_photoCachedSize: {
const string &s(sizes.at(i).c_photoCachedSize().vtype.c_string().v);
auto &s = sizes.at(i).c_photoCachedSize().vtype.c_string().v;
loc = &sizes.at(i).c_photoCachedSize().vlocation;
if (s.size()) size = s[0];
} break;
@ -942,7 +942,7 @@ HistoryDocument::HistoryDocument(HistoryItem *parent, DocumentData *document, co
}
HistoryDocument::HistoryDocument(HistoryItem *parent, const HistoryDocument &other) : HistoryFileMedia(parent)
, Composer()
, RuntimeComposer()
, _data(other._data) {
auto captioned = other.Get<HistoryDocumentCaptioned>();
createComponents(captioned != 0);
@ -2560,7 +2560,7 @@ int HistoryWebPage::resizeGetHeight(int width) {
return _height;
}
_width = qMin(width, _maxw);
_width = width = qMin(width, _maxw);
width -= st::msgPadding.left() + st::webPageLeft + st::msgPadding.right();
int32 linesMax = 5;
@ -2659,10 +2659,10 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, u
auto padding = inBubblePadding();
auto tshift = padding.top();
auto bshift = padding.bottom();
width -= padding.left() + padding.right();
if (_asArticle || (isBubbleBottom() && _attach && _attach->customInfoLayout() && _attach->currentWidth() + _parent->skipBlockWidth() > width + bubble.left() + bubble.right())) {
bshift += bottomInfoPadding();
}
width -= padding.left() + padding.right();
QRect bar(rtlrect(st::msgPadding.left(), tshift, st::webPageBar, _height - tshift - bshift, _width));
p.fillRect(bar, barfg);
@ -2959,7 +2959,8 @@ void HistoryGame::initDimensions() {
_minh = 0;
int32 titleMinHeight = _title.isEmpty() ? 0 : _lineHeight;
int32 descMaxLines = (4 + (titleMinHeight ? 0 : 1));
// enable any count of lines in game description / message
int descMaxLines = 4096;
int32 descriptionMinHeight = _description.isEmpty() ? 0 : qMin(_description.minHeight(), descMaxLines * _lineHeight);
if (!_title.isEmpty()) {
@ -2993,7 +2994,7 @@ void HistoryGame::initDimensions() {
}
int HistoryGame::resizeGetHeight(int width) {
_width = qMin(width, _maxw);
_width = width = qMin(width, _maxw);
width -= st::msgPadding.left() + st::webPageLeft + st::msgPadding.right();
// enable any count of lines in game description / message
@ -3055,10 +3056,10 @@ void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, uint
auto padding = inBubblePadding();
auto tshift = padding.top();
auto bshift = padding.bottom();
width -= padding.left() + padding.right();
if (isBubbleBottom() && _attach && _attach->customInfoLayout() && _attach->currentWidth() + _parent->skipBlockWidth() > width + bubble.left() + bubble.right()) {
bshift += bottomInfoPadding();
}
width -= padding.left() + padding.right();
QRect bar(rtlrect(st::msgPadding.left(), tshift, st::webPageBar, _height - tshift - bshift, _width));
p.fillRect(bar, barfg);

View File

@ -278,17 +278,17 @@ private:
};
struct HistoryDocumentThumbed : public BaseComponent<HistoryDocumentThumbed> {
struct HistoryDocumentThumbed : public RuntimeComponent<HistoryDocumentThumbed> {
ClickHandlerPtr _linksavel, _linkcancell;
int _thumbw = 0;
mutable int _linkw = 0;
mutable QString _link;
};
struct HistoryDocumentCaptioned : public BaseComponent<HistoryDocumentCaptioned> {
struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned> {
Text _caption = { int(st::msgFileMinWidth) - st::msgPadding.left() - st::msgPadding.right() };
};
struct HistoryDocumentNamed : public BaseComponent<HistoryDocumentNamed> {
struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed> {
QString _name;
int _namew = 0;
};
@ -300,7 +300,7 @@ struct HistoryDocumentVoicePlayback {
anim::fvalue a_progress;
Animation _a_progress;
};
struct HistoryDocumentVoice : public BaseComponent<HistoryDocumentVoice> {
struct HistoryDocumentVoice : public RuntimeComponent<HistoryDocumentVoice> {
HistoryDocumentVoice &operator=(HistoryDocumentVoice &&other) {
std::swap(_playback, other._playback);
return *this;
@ -313,7 +313,7 @@ struct HistoryDocumentVoice : public BaseComponent<HistoryDocumentVoice> {
mutable HistoryDocumentVoicePlayback *_playback = nullptr;
};
class HistoryDocument : public HistoryFileMedia, public Composer {
class HistoryDocument : public HistoryFileMedia, public RuntimeComposer {
public:
HistoryDocument(HistoryItem *parent, DocumentData *document, const QString &caption);
HistoryDocument(HistoryItem *parent, const HistoryDocument &other);

View File

@ -1968,7 +1968,7 @@ bool HistoryService::preparePinnedText(const QString &from, QString *outText, Li
bool HistoryService::prepareGameScoreText(const QString &from, QString *outText, Links *outLinks) {
bool result = false;
QString text;
QString gameTitle;
ClickHandlerPtr second;
auto gamescore = Get<HistoryServiceGameScore>();
@ -1976,20 +1976,25 @@ bool HistoryService::prepareGameScoreText(const QString &from, QString *outText,
auto getGameTitle = [item = gamescore->msg, &second]()->QString {
if (auto media = item->getMedia()) {
if (media->type() == MediaTypeGame) {
return static_cast<HistoryGame*>(media)->game()->title;
second = MakeShared<ReplyMarkupClickHandler>(item, 0, 0);
return textcmdLink(2, static_cast<HistoryGame*>(media)->game()->title);
}
}
return lang(lng_deleted_message);
};
text = lng_action_game_score(lt_from, from, lt_count, gamescore->score, lt_game, getGameTitle());
gameTitle = getGameTitle();
result = true;
} else if (gamescore && gamescore->msgId) {
text = lng_action_game_score(lt_from, from, lt_count, gamescore->score, lt_game, lang(lng_contacts_loading));
gameTitle = lang(lng_contacts_loading);
result = true;
} else {
text = lng_action_game_score(lt_from, from, lt_count, gamescore->score, lt_game, lang(lng_deleted_message));
gameTitle = lang(lng_deleted_message);
}
if (_from->isSelf()) {
*outText = lng_action_game_you_scored(lt_count, gamescore->score, lt_game, gameTitle);
} else {
*outText = lng_action_game_score(lt_from, from, lt_count, gamescore->score, lt_game, gameTitle);
}
*outText = text;
if (second) {
outLinks->push_back(second);
}

View File

@ -252,10 +252,10 @@ struct HistoryServiceDependentData {
ClickHandlerPtr lnk;
};
struct HistoryServicePinned : public BaseComponent<HistoryServicePinned>, public HistoryServiceDependentData {
struct HistoryServicePinned : public RuntimeComponent<HistoryServicePinned>, public HistoryServiceDependentData {
};
struct HistoryServiceGameScore : public BaseComponent<HistoryServiceGameScore>, public HistoryServiceDependentData {
struct HistoryServiceGameScore : public RuntimeComponent<HistoryServiceGameScore>, public HistoryServiceDependentData {
int score = 0;
};

View File

@ -303,6 +303,10 @@ QString Result::getLayoutDescription() const {
return sendData->getLayoutDescription(this);
}
// just to make unique_ptr see the destructors.
Result::~Result() {
}
void Result::createPhoto() {
if (_photo) return;

View File

@ -74,6 +74,8 @@ public:
QString getLayoutTitle() const;
QString getLayoutDescription() const;
~Result();
private:
void createPhoto();
void createDocument();

View File

@ -96,7 +96,7 @@ void IntroSignup::mousePressEvent(QMouseEvent *e) {
void IntroSignup::paintEvent(QPaintEvent *e) {
bool trivial = (rect() == e->rect());
QPainter p(this);
Painter p(this);
if (!trivial) {
p.setClipRect(e->rect());
}
@ -123,20 +123,22 @@ void IntroSignup::paintEvent(QPaintEvent *e) {
}
if (_photoSmall.isNull()) {
if (a_photoOver.current() < 1) {
QRect pix(st::setPhotoImg.rect());
pix.moveTo(pix.x() + (pix.width() - (st::introPhotoSize * cIntRetinaFactor())) / 2, pix.y() + (pix.height() - (st::introPhotoSize * cIntRetinaFactor())) / 2);
pix.setSize(QSize(st::introPhotoSize * cIntRetinaFactor(), st::introPhotoSize * cIntRetinaFactor()));
p.drawPixmap(QPoint(_phLeft, _phTop), App::sprite(), pix);
}
if (a_photoOver.current() > 0) {
QRect pix(st::setOverPhotoImg.rect());
pix.moveTo(pix.x() + (pix.width() - (st::introPhotoSize * cIntRetinaFactor())) / 2, pix.y() + (pix.height() - (st::introPhotoSize * cIntRetinaFactor())) / 2);
pix.setSize(QSize(st::introPhotoSize * cIntRetinaFactor(), st::introPhotoSize * cIntRetinaFactor()));
p.setOpacity(a_photoOver.current());
p.drawPixmap(QPoint(_phLeft, _phTop), App::sprite(), pix);
p.setOpacity(1);
float64 o = a_photoOver.current();
QRect phRect(_phLeft, _phTop, st::introPhotoSize, st::introPhotoSize);
if (o > 0) {
if (o < 1) {
QColor c;
c.setRedF(st::newGroupPhotoBg->c.redF() * (1. - o) + st::newGroupPhotoBgOver->c.redF() * o);
c.setGreenF(st::newGroupPhotoBg->c.greenF() * (1. - o) + st::newGroupPhotoBgOver->c.greenF() * o);
c.setBlueF(st::newGroupPhotoBg->c.blueF() * (1. - o) + st::newGroupPhotoBgOver->c.blueF() * o);
p.fillRect(phRect, c);
} else {
p.fillRect(phRect, st::newGroupPhotoBgOver);
}
} else {
p.fillRect(phRect, st::newGroupPhotoBg);
}
p.drawSpriteCenter(phRect, st::newGroupPhotoIcon);
} else {
p.drawPixmap(_phLeft, _phTop, _photoSmall);
}

View File

@ -151,7 +151,7 @@ bool LangLoaderPlain::readKeyValue(const char *&from, const char *end) {
tagReplacer[1] = TextCommandLangTag;
tagReplacer[2] = QChar(0x0020 + index);
varValue.append(tagReplacer.toUtf8());
if (*from == ':') {
start = ++from;
@ -306,7 +306,7 @@ LangLoaderPlain::LangLoaderPlain(const QString &file, const LangLoaderRequest &r
break;
}
}
} catch (exception &e) {
} catch (std::exception &e) {
error(QString::fromUtf8(e.what()));
return;
}

View File

@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#pragma once
#include "core/runtime_composer.h"
static constexpr TextSelection FullSelection = { 0xFFFF, 0xFFFF };
extern TextParseOptions _textNameOptions, _textDlgOptions;
@ -96,7 +98,7 @@ public:
};
class LayoutItemBase : public Composer, public ClickHandlerHost {
class LayoutItemBase : public RuntimeComposer, public ClickHandlerHost {
public:
LayoutItemBase() {
}

View File

@ -19,10 +19,11 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "logs.h"
#include <signal.h>
#include <new>
#include "pspecific.h"
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
@ -736,6 +737,22 @@ namespace internal {
namespace internal {
struct SomeAllocatedMemoryChunk {
char data[1024 * 1024];
};
std_::unique_ptr<SomeAllocatedMemoryChunk> SomeAllocatedMemory;
void OperatorNewHandler() {
std::set_new_handler(nullptr);
SomeAllocatedMemory.reset();
t_assert(!"Could not allocate!");
}
void InstallOperatorNewHandler() {
SomeAllocatedMemory = std_::make_unique<SomeAllocatedMemoryChunk>();
std::set_new_handler(OperatorNewHandler);
}
Qt::HANDLE ReportingThreadId = nullptr;
bool ReportingHeaderWritten = false;
QMutex ReportingMutex;
@ -1078,6 +1095,9 @@ namespace internal {
signal(SIGFPE, SignalHandlers::internal::Handler);
#endif // else for !Q_OS_WIN
}
SignalHandlers::internal::InstallOperatorNewHandler();
return Started;
}

View File

@ -959,31 +959,31 @@ HitTestType MainWindow::hitTest(const QPoint &p) const {
if (!windowState().testFlag(Qt::WindowMaximized)) {
if (y < raw) {
if (x < raw) {
return HitTestTopLeft;
return HitTestType::TopLeft;
} else if (x > w - raw - 1) {
return HitTestTopRight;
return HitTestType::TopRight;
}
return HitTestTop;
return HitTestType::Top;
} else if (y > h - raw - 1) {
if (x < raw) {
return HitTestBottomLeft;
return HitTestType::BottomLeft;
} else if (x > w - raw - 1) {
return HitTestBottomRight;
return HitTestType::BottomRight;
}
return HitTestBottom;
return HitTestType::Bottom;
} else if (x < raw) {
return HitTestLeft;
return HitTestType::Left;
} else if (x > w - raw - 1) {
return HitTestRight;
return HitTestType::Right;
}
}
HitTestType titleTest = title->hitTest(p - title->geometry().topLeft());
if (titleTest) {
auto titleTest = title->hitTest(p - title->geometry().topLeft());
if (titleTest != HitTestType::None) {
return titleTest;
} else if (x >= 0 && y >= 0 && x < w && y < h) {
return HitTestClient;
return HitTestType::Client;
}
return HitTestNone;
return HitTestType::None;
}
QRect MainWindow::iconRect() const {

View File

@ -171,6 +171,11 @@ private:
};
template <typename ...Args>
inline ReaderPointer MakeReader(Args&&... args) {
return ReaderPointer(new Reader(std_::forward<Args>(args)...));
}
enum class ProcessResult {
Error,
Started,

View File

@ -162,7 +162,7 @@ private:
int32 handleOneReceived(const mtpPrime *from, const mtpPrime *end, uint64 msgId, int32 serverTime, uint64 serverSalt, bool badTime);
mtpBuffer ungzip(const mtpPrime *from, const mtpPrime *end) const;
void handleMsgsStates(const QVector<MTPlong> &ids, const string &states, QVector<MTPlong> &acked);
void handleMsgsStates(const QVector<MTPlong> &ids, const std::string &states, QVector<MTPlong> &acked);
void clearMessages();

View File

@ -665,7 +665,7 @@ class MTPDstring : public mtpDataImpl<MTPDstring> {
public:
MTPDstring() {
}
MTPDstring(const string &val) : v(val) {
MTPDstring(const std::string &val) : v(val) {
}
MTPDstring(const QString &val) : v(val.toUtf8().constData()) {
}
@ -674,7 +674,7 @@ public:
MTPDstring(const char *val) : v(val) {
}
string v;
std::string v;
};
class MTPstring : private mtpDataOwner {
@ -755,13 +755,13 @@ private:
explicit MTPstring(MTPDstring *_data) : mtpDataOwner(_data) {
}
friend MTPstring MTP_string(const string &v);
friend MTPstring MTP_string(const std::string &v);
friend MTPstring MTP_string(const QString &v);
friend MTPstring MTP_string(const char *v);
friend MTPstring MTP_bytes(const QByteArray &v);
};
inline MTPstring MTP_string(const string &v) {
inline MTPstring MTP_string(const std::string &v) {
return MTPstring(new MTPDstring(v));
}
inline MTPstring MTP_string(const QString &v) {
@ -788,12 +788,12 @@ inline bool operator!=(const MTPstring &a, const MTPstring &b) {
}
inline QString qs(const MTPstring &v) {
const string &d(v.c_string().v);
auto &d = v.c_string().v;
return QString::fromUtf8(d.data(), d.length());
}
inline QByteArray qba(const MTPstring &v) {
const string &d(v.c_string().v);
auto &d = v.c_string().v;
return QByteArray(d.data(), d.length());
}
@ -981,8 +981,6 @@ inline bool mtpIsFalse(const MTPBool &v) {
return !mtpIsTrue(v);
}
#define CHECK_MTP_SCHEME_AND_CLIENT_FLAGS_CONFLICT(Type) \
// we must validate that MTProto scheme flags don't intersect with client side flags
// and define common bit operators which allow use Type_ClientFlag together with Type::Flag
#define DEFINE_MTP_CLIENT_FLAGS(Type) \
@ -990,12 +988,10 @@ static_assert(static_cast<int32>(Type::Flag::MAX_FIELD) < static_cast<int32>(Typ
"MTProto flags conflict with client side flags!"); \
inline Type::Flags qFlags(Type##_ClientFlag v) { return Type::Flags(static_cast<int32>(v)); } \
inline Type::Flags operator&(Type::Flags i, Type##_ClientFlag v) { return i & qFlags(v); } \
inline Type::Flags operator&(Type::Flag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
inline Type::Flags operator&(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) & v; } \
inline Type::Flags operator&(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) & v; } \
inline Type::Flags &operator&=(Type::Flags &i, Type##_ClientFlag v) { return i &= qFlags(v); } \
inline Type::Flags operator|(Type::Flags i, Type##_ClientFlag v) { return i | qFlags(v); } \
inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
inline Type::Flags operator|(Type::Flag i, Type##_ClientFlag v) { return i | qFlags(v); } \
inline Type::Flags operator|(Type##_ClientFlag i, Type##_ClientFlag v) { return qFlags(i) | v; } \
inline Type::Flags operator|(Type##_ClientFlag i, Type::Flag v) { return qFlags(i) | v; } \
inline Type::Flags &operator|=(Type::Flags &i, Type##_ClientFlag v) { return i |= qFlags(v); } \

View File

@ -198,12 +198,12 @@ void setKey(int32 dc, AuthKeyPtr key);
QReadWriteLock *dcOptionsMutex();
struct DcOption {
DcOption(int id, MTPDdcOption::Flags flags, const string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
DcOption(int id, MTPDdcOption::Flags flags, const std::string &ip, int port) : id(id), flags(flags), ip(ip), port(port) {
}
int id;
MTPDdcOption::Flags flags;
string ip;
std::string ip;
int port;
};
typedef QMap<int, DcOption> DcOptions;

View File

@ -459,8 +459,8 @@ void mtpFileLoader::partLoaded(int32 offset, const MTPupload_File &result, mtpRe
--_queue->queries;
_requests.erase(i);
const auto &d(result.c_upload_file());
const string &bytes(d.vbytes.c_string().v);
auto &d = result.c_upload_file();
auto &bytes = d.vbytes.c_string().v;
if (DebugLogging::FileLoader() && _id) DEBUG_LOG(("FileLoader(%1): got part with offset=%2, bytes=%3, _queue->queries=%4, _nextRequestOffset=%5, _requests=%6").arg(_id).arg(offset).arg(bytes.size()).arg(_queue->queries).arg(_nextRequestOffset).arg(serializereqs(_requests)));

View File

@ -34,7 +34,7 @@ public:
uint64 getFingerPrint() const;
// data has exactly 256 chars to be encrypted
bool encrypt(const void *data, string &result) const;
bool encrypt(const void *data, std::string &result) const;
private:

View File

@ -222,7 +222,7 @@ void Session::sendPong(quint64 msgId, quint64 pingId) {
void Session::sendMsgsStateInfo(quint64 msgId, QByteArray data) {
MTPMsgsStateInfo req(MTP_msgs_state_info(MTP_long(msgId), MTPstring()));
string &info(req._msgs_state_info().vinfo._string().v);
auto &info = req._msgs_state_info().vinfo._string().v;
info.resize(data.size());
if (!data.isEmpty()) {
memcpy(&info[0], data.constData(), data.size());
@ -391,7 +391,7 @@ mtpRequestId Session::resend(quint64 msgId, quint64 msCanWait, bool forceContain
char cantResend[2] = {1, 0};
DEBUG_LOG(("Message Info: cant resend %1, request not found").arg(msgId));
return send(MTP_msgs_state_info(MTP_long(msgId), MTP_string(string(cantResend, cantResend + 1))));
return send(MTP_msgs_state_info(MTP_long(msgId), MTP_string(std::string(cantResend, cantResend + 1))));
}
return 0;
}

View File

@ -156,7 +156,7 @@ protected:
};
struct Info : public BaseComponent<Info> {
struct Info : public RuntimeComponent<Info> {
int top = 0;
};

View File

@ -186,7 +186,7 @@ void PasscodeWidget::paintEvent(QPaintEvent *e) {
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow.rect());
} else {
p.fillRect(rect(), st::setBG->b);
p.fillRect(rect(), st::windowBg);
p.setFont(st::passcodeHeaderFont->f);
p.drawText(QRect(0, _passcode.y() - st::passcodeHeaderHeight, width(), st::passcodeHeaderHeight), lang(lng_passcode_enter), style::al_center);

View File

@ -181,21 +181,21 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
POINTS p = MAKEPOINTS(lParam);
RECT r;
GetWindowRect(hWnd, &r);
HitTestType res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
switch (res) {
case HitTestClient:
case HitTestSysButton: *result = HTCLIENT; break;
case HitTestIcon: *result = HTCAPTION; break;
case HitTestCaption: *result = HTCAPTION; break;
case HitTestTop: *result = HTTOP; break;
case HitTestTopRight: *result = HTTOPRIGHT; break;
case HitTestRight: *result = HTRIGHT; break;
case HitTestBottomRight: *result = HTBOTTOMRIGHT; break;
case HitTestBottom: *result = HTBOTTOM; break;
case HitTestBottomLeft: *result = HTBOTTOMLEFT; break;
case HitTestLeft: *result = HTLEFT; break;
case HitTestTopLeft: *result = HTTOPLEFT; break;
case HitTestNone:
case HitTestType::Client:
case HitTestType::SysButton: *result = HTCLIENT; break;
case HitTestType::Icon: *result = HTCAPTION; break;
case HitTestType::Caption: *result = HTCAPTION; break;
case HitTestType::Top: *result = HTTOP; break;
case HitTestType::TopRight: *result = HTTOPRIGHT; break;
case HitTestType::Right: *result = HTRIGHT; break;
case HitTestType::BottomRight: *result = HTBOTTOMRIGHT; break;
case HitTestType::Bottom: *result = HTBOTTOM; break;
case HitTestType::BottomLeft: *result = HTBOTTOMLEFT; break;
case HitTestType::Left: *result = HTLEFT; break;
case HitTestType::TopLeft: *result = HTTOPLEFT; break;
case HitTestType::None:
default: *result = HTTRANSPARENT; break;
};
} return true;
@ -208,9 +208,9 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
POINTS p = MAKEPOINTS(lParam);
RECT r;
GetWindowRect(hWnd, &r);
HitTestType res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
switch (res) {
case HitTestIcon:
case HitTestType::Icon:
if (menuHidden && getms() < menuHidden + 10) {
menuHidden = 0;
if (getms() < menuShown + GetDoubleClickTime()) {
@ -234,9 +234,9 @@ bool EventFilter::mainWindowEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
POINTS p = MAKEPOINTS(lParam);
RECT r;
GetWindowRect(hWnd, &r);
HitTestType res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
auto res = App::wnd()->hitTest(QPoint(p.x - r.left + App::wnd()->deltaLeft(), p.y - r.top + App::wnd()->deltaTop()));
switch (res) {
case HitTestIcon: App::wnd()->close(); return true;
case HitTestType::Icon: App::wnd()->close(); return true;
};
} return false;

View File

@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "localstorage.h"
#include "passcodewidget.h"
#include "history/history_location_manager.h"
#include <execinfo.h>

View File

@ -185,39 +185,39 @@ void settingsParseArgs(int argc, char *argv[]) {
gStartUrl = fromUtf8Safe(argv[1]);
}
for (int32 i = 0; i < argc; ++i) {
if (string("-testmode") == argv[i]) {
if (qstr("-testmode") == argv[i]) {
gTestMode = true;
} else if (string("-debug") == argv[i]) {
} else if (qstr("-debug") == argv[i]) {
gDebug = true;
} else if (string("-many") == argv[i]) {
} else if (qstr("-many") == argv[i]) {
gManyInstance = true;
} else if (string("-key") == argv[i] && i + 1 < argc) {
} else if (qstr("-key") == argv[i] && i + 1 < argc) {
gKeyFile = fromUtf8Safe(argv[++i]);
} else if (string("-autostart") == argv[i]) {
} else if (qstr("-autostart") == argv[i]) {
gLaunchMode = LaunchModeAutoStart;
} else if (string("-fixprevious") == argv[i]) {
} else if (qstr("-fixprevious") == argv[i]) {
gLaunchMode = LaunchModeFixPrevious;
} else if (string("-cleanup") == argv[i]) {
} else if (qstr("-cleanup") == argv[i]) {
gLaunchMode = LaunchModeCleanup;
} else if (string("-crash") == argv[i] && i + 1 < argc) {
} else if (qstr("-crash") == argv[i] && i + 1 < argc) {
gLaunchMode = LaunchModeShowCrash;
gStartUrl = fromUtf8Safe(argv[++i]);
} else if (string("-noupdate") == argv[i]) {
} else if (qstr("-noupdate") == argv[i]) {
gNoStartUpdate = true;
} else if (string("-tosettings") == argv[i]) {
} else if (qstr("-tosettings") == argv[i]) {
gStartToSettings = true;
} else if (string("-startintray") == argv[i]) {
} else if (qstr("-startintray") == argv[i]) {
gStartInTray = true;
} else if (string("-sendpath") == argv[i] && i + 1 < argc) {
} else if (qstr("-sendpath") == argv[i] && i + 1 < argc) {
for (++i; i < argc; ++i) {
gSendPaths.push_back(fromUtf8Safe(argv[i]));
}
} else if (string("-workdir") == argv[i] && i + 1 < argc) {
} else if (qstr("-workdir") == argv[i] && i + 1 < argc) {
QString dir = fromUtf8Safe(argv[++i]);
if (QDir().exists(dir)) {
gWorkingDir = dir;
}
} else if (string("--") == argv[i] && i + 1 < argc) {
} else if (qstr("--") == argv[i] && i + 1 < argc) {
gStartUrl = fromUtf8Safe(argv[++i]).mid(0, 8192);
}
}

View File

@ -59,8 +59,8 @@ void BackgroundRow::paintEvent(QPaintEvent *e) {
if (backThumb->isNull()) {
p.drawPixmap(0, 0, _background);
} else {
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::setBackgroundSize);
p.drawPixmap(0, 0, st::setBackgroundSize, st::setBackgroundSize, pix, 0, (pix.height() - st::setBackgroundSize) / 2, st::setBackgroundSize, st::setBackgroundSize);
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::settingsBackgroundSize);
p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, 0, (pix.height() - st::settingsBackgroundSize) / 2, st::settingsBackgroundSize, st::settingsBackgroundSize);
}
auto outer = radialRect();
@ -115,7 +115,7 @@ bool BackgroundRow::radialLoading() const {
}
QRect BackgroundRow::radialRect() const {
return QRect(0, 0, st::setBackgroundSize, st::setBackgroundSize);
return QRect(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize);
}
void BackgroundRow::radialStart() {
@ -139,7 +139,7 @@ void BackgroundRow::step_radial(uint64 ms, bool timer) {
}
void BackgroundRow::updateImage() {
int32 size = st::setBackgroundSize * cIntRetinaFactor();
int32 size = st::settingsBackgroundSize * cIntRetinaFactor();
QImage back(size, size, QImage::Format_ARGB32_Premultiplied);
back.setDevicePixelRatio(cRetinaFactor());
{
@ -149,7 +149,7 @@ void BackgroundRow::updateImage() {
int sy = (pix.height() > pix.width()) ? ((pix.height() - pix.width()) / 2) : 0;
int s = (pix.width() > pix.height()) ? pix.height() : pix.width();
p.setRenderHint(QPainter::SmoothPixmapTransform);
p.drawPixmap(0, 0, st::setBackgroundSize, st::setBackgroundSize, pix, sx, sy, s, s);
p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, sx, sy, s, s);
}
imageRound(back, ImageRoundRadius::Small);
_background = App::pixmapFromImageInPlace(std_::move(back));

View File

@ -57,6 +57,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include <QtNetwork/QtNetwork>
#include "core/basic_types.h"
#include "logs.h"
#include "core/utils.h"
#include "config.h"
#include "mtproto/facade.h"

View File

@ -172,7 +172,7 @@ struct NotifySettings {
}
MTPDpeerNotifySettings::Flags flags;
TimeId mute;
string sound;
std::string sound;
bool previews() const {
return flags & MTPDpeerNotifySettings::Flag::f_show_previews;
}
@ -288,9 +288,9 @@ public:
QString name;
Text nameText;
typedef QSet<QString> Names;
using Names = OrderedSet<QString>;
Names names; // for filtering
typedef QSet<QChar> NameFirstChars;
using NameFirstChars = OrderedSet<QChar>;
NameFirstChars chars;
enum LoadedStatus {

View File

@ -92,9 +92,9 @@ void SysBtn::setSysBtnStyle(const style::sysButton &st) {
HitTestType SysBtn::hitTest(const QPoint &p) const {
int x(p.x()), y(p.y()), w(width()), h(height());
if (x >= 0 && y >= 0 && x < w && y < h && isVisible()) {
return HitTestSysButton;
return HitTestType::SysButton;
}
return HitTestNone;
return HitTestType::None;
}
void SysBtn::step_color(float64 ms, bool timer) {

View File

@ -23,6 +23,22 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "ui/animation.h"
#include "ui/button.h"
enum class HitTestType {
None = 0,
Client,
SysButton,
Icon,
Caption,
Top,
TopRight,
Right,
BottomRight,
Bottom,
BottomLeft,
Left,
TopLeft,
};
class SysBtn : public Button {
public:
SysBtn(QWidget *parent, const style::sysButton &st, const QString &text = QString());

View File

@ -385,23 +385,23 @@ void TitleWidget::maximizedChanged(bool maximized, bool force) {
}
HitTestType TitleWidget::hitTest(const QPoint &p) {
if (App::wnd() && Ui::isLayerShown()) return HitTestNone;
if (App::wnd() && Ui::isLayerShown()) return HitTestType::None;
int x(p.x()), y(p.y()), w(width()), h(height());
if (!Adaptive::OneColumn() && _hider && x >= App::main()->dlgsWidth()) return HitTestNone;
if (!Adaptive::OneColumn() && _hider && x >= App::main()->dlgsWidth()) return HitTestType::None;
if (x >= st::titleIconPos.x() && y >= st::titleIconPos.y() && x < st::titleIconPos.x() + st::titleIconImg.pxWidth() && y < st::titleIconPos.y() + st::titleIconImg.pxHeight()) {
return HitTestIcon;
return HitTestType::Icon;
} else if (false
|| (_player && _player->geometry().contains(p))
|| (_lock.hitTest(p - _lock.geometry().topLeft()) == HitTestSysButton && _lock.isVisible())
|| (_update.hitTest(p - _update.geometry().topLeft()) == HitTestSysButton && _update.isVisible())
|| (_minimize.hitTest(p - _minimize.geometry().topLeft()) == HitTestSysButton)
|| (_maximize.hitTest(p - _maximize.geometry().topLeft()) == HitTestSysButton)
|| (_restore.hitTest(p - _restore.geometry().topLeft()) == HitTestSysButton)
|| (_close.hitTest(p - _close.geometry().topLeft()) == HitTestSysButton)
|| (_lock.hitTest(p - _lock.geometry().topLeft()) == HitTestType::SysButton && _lock.isVisible())
|| (_update.hitTest(p - _update.geometry().topLeft()) == HitTestType::SysButton && _update.isVisible())
|| (_minimize.hitTest(p - _minimize.geometry().topLeft()) == HitTestType::SysButton)
|| (_maximize.hitTest(p - _maximize.geometry().topLeft()) == HitTestType::SysButton)
|| (_restore.hitTest(p - _restore.geometry().topLeft()) == HitTestType::SysButton)
|| (_close.hitTest(p - _close.geometry().topLeft()) == HitTestType::SysButton)
) {
return HitTestSysButton;
return HitTestType::SysButton;
} else if (x >= 0 && x < w && y >= 0 && y < h) {
if (false
|| (!_cancel.isHidden() && _cancel.geometry().contains(x, y))
@ -409,9 +409,9 @@ HitTestType TitleWidget::hitTest(const QPoint &p) {
|| (!_contacts.isHidden() && _contacts.geometry().contains(x, y))
|| (!_about.isHidden() && _about.geometry().contains(x, y))
) {
return HitTestClient;
return HitTestType::Client;
}
return HitTestCaption;
return HitTestType::Caption;
}
return HitTestNone;
return HitTestType::None;
}

View File

@ -35,11 +35,6 @@ ReaderPointer::~ReaderPointer() {
_pointer = nullptr;
}
class Tmp;
void f(Tmp *t) {
delete t;
}
} // namespace Clip
} // namespace Media

View File

@ -31,7 +31,7 @@ namespace Clip {
class Reader;
class ReaderPointer {
public:
ReaderPointer(std::nullptr_t = nullptr) {
ReaderPointer(std_::nullptr_t = nullptr) {
}
explicit ReaderPointer(Reader *pointer) : _pointer(pointer) {
}
@ -77,11 +77,6 @@ private:
};
template <typename ...Args>
inline ReaderPointer MakeReader(Args&&... args) {
return ReaderPointer(new Reader(std_::forward<Args>(args)...));
}
class Manager;
enum Notification {

View File

@ -26,8 +26,7 @@ class FlatCheckbox : public Button {
Q_OBJECT
public:
FlatCheckbox(QWidget *parent, const QString &text, bool checked = false, const style::flatCheckbox &st = st::cbDefFlat);
FlatCheckbox(QWidget *parent, const QString &text, bool checked, const style::flatCheckbox &st);
bool checked() const;
void setChecked(bool checked);
@ -38,16 +37,13 @@ public:
void setOpacity(float64 o);
public slots:
void onClicked();
void onStateChange(int oldState, ButtonStateChangeSource source);
signals:
void changed();
private:
style::flatCheckbox _st;
anim::fvalue a_over;
Animation _a_appearance;
@ -66,7 +62,7 @@ class FlatRadiobutton : public FlatCheckbox {
public:
FlatRadiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked = false, const style::flatCheckbox &st = st::rbDefFlat);
FlatRadiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked, const style::flatCheckbox &st);
int32 val() const {
return _value;
}
@ -130,7 +126,6 @@ class Radiobutton : public Button {
Q_OBJECT
public:
Radiobutton(QWidget *parent, const QString &group, int32 value, const QString &text, bool checked = false, const style::Radiobutton &st = st::defaultRadiobutton);
bool checked() const;
@ -148,16 +143,13 @@ public:
~Radiobutton();
public slots:
void onClicked();
void onStateChange(int oldState, ButtonStateChangeSource source);
signals:
void changed();
private:
void onChanged();
const style::Radiobutton &_st;

View File

@ -310,7 +310,7 @@ private:
template <typename T>
class ChildWidget {
public:
ChildWidget(std::nullptr_t) : _widget(nullptr) {
ChildWidget(std_::nullptr_t) : _widget(nullptr) {
}
// No default constructor, but constructors with at least
@ -322,7 +322,7 @@ public:
ChildWidget(const ChildWidget<T> &other) = delete;
ChildWidget<T> &operator=(const ChildWidget<T> &other) = delete;
ChildWidget<T> &operator=(std::nullptr_t) {
ChildWidget<T> &operator=(std_::nullptr_t) {
_widget = nullptr;
return *this;
}

View File

@ -3,4 +3,4 @@ AppVersionStrMajor 0.10
AppVersionStrSmall 0.10.8
AppVersionStr 0.10.8
AlphaChannel 0
BetaVersion 10008001
BetaVersion 10008003

View File

@ -192,7 +192,6 @@
'<(src_loc)/boxes/stickersetbox.h',
'<(src_loc)/boxes/usernamebox.cpp',
'<(src_loc)/boxes/usernamebox.h',
'<(src_loc)/core/basic_types.cpp',
'<(src_loc)/core/basic_types.h',
'<(src_loc)/core/click_handler.cpp',
'<(src_loc)/core/click_handler.h',
@ -201,8 +200,14 @@
'<(src_loc)/core/lambda_wrap.h',
'<(src_loc)/core/observer.cpp',
'<(src_loc)/core/observer.h',
'<(src_loc)/core/ordered_set.h',
'<(src_loc)/core/qthelp_url.cpp',
'<(src_loc)/core/qthelp_url.h',
'<(src_loc)/core/runtime_composer.cpp',
'<(src_loc)/core/runtime_composer.h',
'<(src_loc)/core/stl_subset.h',
'<(src_loc)/core/utils.cpp',
'<(src_loc)/core/utils.h',
'<(src_loc)/core/vector_of_moveable.h',
'<(src_loc)/core/version.h',
'<(src_loc)/data/data_abstract_structure.cpp',