mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-04-01 14:50:24 +00:00
merged to master
This commit is contained in:
commit
f24b5fc35b
Telegram
PrepareMac.shPrepareWin.bat
Resources
SourceFiles
app.cppapp.happlication.cppapplication.h
Telegram.plistTelegram.rcTelegram.vcxprojart
autoupdater.cppautoupdater.hboxes
config.hdialogswidget.cppdialogswidget.hgui
history.cpphistory.hhistorywidget.cppintro
lang.hlangs
localstorage.cppmain.cppmainwidget.cppmainwidget.hmtproto
overviewwidget.cppoverviewwidget.hprofilewidget.cppprofilewidget.hpspecific_linux.cpppspecific_mac.cpppspecific_wnd.cppsettings.cppsettings.hsettingswidget.cppsettingswidget.hstructs.cppstructs.hsysbuttons.cpptitle.cpptypes.hTelegram.xcodeproj
UpdateLang.shVersion.sh_qt_5_5_0_patch.diff_qt_5_5_0_patch/qtbase/src/plugins/platforms/windows
@ -92,5 +92,6 @@ rm ./../Mac/Release/Telegram.app/Contents/Frameworks/Updater
|
||||
rm -rf ./../Mac/Release/Telegram.app/Contents/_CodeSignature
|
||||
mv ./../Mac/Release/tmacupd$AppVersion ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/
|
||||
mv ./../Mac/Release/tsetup.$AppVersionStr$DevPostfix.dmg ./../Mac/Release/deploy/$AppVersionStrMajor/$AppVersionStr$DevPostfix/tsetup.$AppVersionStr$DevPostfix.dmg
|
||||
|
||||
echo "Version $AppVersionStr$DevPostfix prepared!";
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
@echo OFF
|
||||
|
||||
set "AppVersionStrMajor=0.8"
|
||||
set "AppVersion=8051"
|
||||
set "AppVersionStrSmall=0.8.51"
|
||||
set "AppVersionStr=0.8.51"
|
||||
set "AppVersionStrFull=0.8.51.0"
|
||||
set "AppVersion=8055"
|
||||
set "AppVersionStrSmall=0.8.55"
|
||||
set "AppVersionStr=0.8.55"
|
||||
set "AppVersionStrFull=0.8.55.0"
|
||||
set "DevChannel=0"
|
||||
|
||||
if %DevChannel% neq 0 goto preparedev
|
||||
|
@ -60,6 +60,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "Sunday";
|
||||
|
||||
"lng_month_day" = "{month} {day}";
|
||||
"lng_month_day_year" = "{month} {day}, {year}";
|
||||
|
||||
"lng_cancel" = "Cancel";
|
||||
"lng_continue" = "Continue";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "Your code";
|
||||
"lng_code_desc" = "We have sent you a message with activation\ncode to your phone. Please enter it below.";
|
||||
"lng_code_telegram" = "Please enter the code you've just\nreceived in your previous [b]Telegram[/b] app.";
|
||||
"lng_code_no_telegram" = "Send code via SMS";
|
||||
"lng_code_call" = "Telegram will dial your number in {minutes}:{seconds}";
|
||||
"lng_code_calling" = "Requesting a call from Telegram..";
|
||||
"lng_code_called" = "Telegram dialed your number";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Show message preview";
|
||||
"lng_settings_use_windows" = "Use Windows notifications";
|
||||
"lng_settings_sound_notify" = "Play sound";
|
||||
"lng_settings_include_muted" = "Include muted chats in unread count";
|
||||
|
||||
"lng_notification_preview" = "You have a new message";
|
||||
|
||||
@ -386,6 +390,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Files overview";
|
||||
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages} »";
|
||||
"lng_profile_audios_header" = "Voice messages overview";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links} »";
|
||||
"lng_profile_shared_links_header" = "Shared links overview";
|
||||
"lng_profile_audio_files_header" = "Playlist";
|
||||
"lng_profile_show_all_types" = "Show all types";
|
||||
"lng_profile_copy_phone" = "Copy phone number";
|
||||
@ -443,6 +449,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "Video files";
|
||||
"lng_media_type_files" = "Files";
|
||||
"lng_media_type_audios" = "Voice messages";
|
||||
"lng_media_type_links" = "Shared links";
|
||||
|
||||
"lng_media_open_with" = "Open With";
|
||||
"lng_media_download" = "Download";
|
||||
@ -641,7 +648,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop was updated to version {version}\n\n{changes}\n\nFull version history is available here:\n{link}";
|
||||
"lng_new_version_minor" = "— Bug fixes and other minor improvements";
|
||||
"lng_new_version_text" = "— Block users from their profile page\n— Added support for Windows toast notifications\n— Fixed input methods on Linux (Fcitx and IBus)";
|
||||
"lng_new_version_text" = "— Include muted chats in unread count in Settings\n— Shared links overview and search in shared media\n— Preview when sending links to GIF animations and PDF files";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insert Unicode control character";
|
||||
|
||||
|
@ -374,6 +374,10 @@ introHeaderFont: font(24px);
|
||||
introHeaderSkip: 14px;
|
||||
introIconSkip: 54px;
|
||||
introFont: font(16px);
|
||||
introLink: linkButton(btnDefLink) {
|
||||
font: introFont;
|
||||
overFont: font(16px underline);
|
||||
}
|
||||
introColor: black;
|
||||
introLabel: flatLabel(labelDefFlat) {
|
||||
font: introFont;
|
||||
@ -1485,6 +1489,10 @@ dropdownMediaAudios: iconedButton(dropdownMediaDocuments) {
|
||||
icon: sprite(62px, 348px, 24px, 24px);
|
||||
downIcon: sprite(62px, 348px, 24px, 24px);
|
||||
}
|
||||
dropdownMediaLinks: iconedButton(dropdownMediaDocuments) {
|
||||
icon: sprite(372px, 414px, 24px, 24px);
|
||||
downIcon: sprite(62px, 348px, 24px, 24px);
|
||||
}
|
||||
|
||||
dragFont: font(28px semibold);
|
||||
dragSubfont: font(20px semibold);
|
||||
@ -2036,3 +2044,15 @@ playerDuration: 200;
|
||||
|
||||
playlistHoverBg: #f2f2f2;
|
||||
playlistPadding: 10px;
|
||||
|
||||
linksSearchMargin: margins(20px, 20px, 20px, 0px);
|
||||
linksMaxWidth: 520px;
|
||||
linksLetterFont: font(24px);
|
||||
linksMargin: 5px;
|
||||
linksBorder: 1px;
|
||||
linksBorderColor: #eaeaea;
|
||||
linksDateColor: #000;
|
||||
linksDateMargin: 15px;
|
||||
|
||||
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
||||
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
||||
|
@ -70,6 +70,9 @@ namespace {
|
||||
typedef QMap<HistoryItem*, QMap<HistoryReply*, bool> > RepliesTo;
|
||||
RepliesTo repliesTo;
|
||||
|
||||
typedef QMap<int32, QString> SharedContactPhones;
|
||||
SharedContactPhones sharedContactPhones;
|
||||
|
||||
Histories histories;
|
||||
|
||||
typedef QHash<MsgId, HistoryItem*> MsgsData;
|
||||
@ -79,6 +82,9 @@ namespace {
|
||||
typedef QMap<uint64, MsgId> RandomData;
|
||||
RandomData randomData;
|
||||
|
||||
typedef QMap<uint64, QString> SentTextData;
|
||||
SentTextData sentTextData;
|
||||
|
||||
HistoryItem *hoveredItem = 0, *pressedItem = 0, *hoveredLinkItem = 0, *pressedLinkItem = 0, *contextItem = 0, *mousedItem = 0;
|
||||
|
||||
QPixmap *sprite = 0, *emojis = 0, *emojisLarge = 0;
|
||||
@ -523,26 +529,6 @@ namespace App {
|
||||
data->left = false;
|
||||
data->forbidden = true;
|
||||
} break;
|
||||
case mtpc_geoChat: {
|
||||
const MTPDgeoChat &d(chat.c_geoChat());
|
||||
data = 0;
|
||||
/* title = qs(d.vtitle);
|
||||
|
||||
PeerId peer(peerFromChat(d.vid.v));
|
||||
data = App::chat(peer);
|
||||
data->input = MTP_inputPeerChat(d.vid);
|
||||
data->setPhoto(d.vphoto);
|
||||
data->date = d.vdate.v;
|
||||
data->count = d.vparticipants_count.v;
|
||||
data->left = false;
|
||||
data->forbidden = false;
|
||||
data->access = d.vaccess_hash.v;
|
||||
if (data->version < d.vversion.v) {
|
||||
data->version = d.vversion.v;
|
||||
data->participants = ChatData::Participants();
|
||||
data->botStatus = 0;
|
||||
}/**/
|
||||
} break;
|
||||
}
|
||||
if (!data) continue;
|
||||
|
||||
@ -716,13 +702,33 @@ namespace App {
|
||||
}
|
||||
}
|
||||
|
||||
void checkEntitiesUpdate(const MTPDmessage &m) {
|
||||
if (HistoryItem *existing = App::histItemById(m.vid.v)) {
|
||||
bool hasLinks = m.has_entities() && !m.ventities.c_vector().v.isEmpty();
|
||||
if ((hasLinks && !existing->hasTextLinks()) || (!hasLinks && existing->textHasLinks())) {
|
||||
existing->setText(qs(m.vmessage), m.has_entities() ? linksFromMTP(m.ventities.c_vector().v) : LinksInText());
|
||||
existing->initDimensions(0);
|
||||
if (App::main()) App::main()->itemResized(existing);
|
||||
if (existing->hasTextLinks()) {
|
||||
existing->history()->addToOverview(existing, OverviewLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState) {
|
||||
const QVector<MTPMessage> &v(msgs.c_vector().v);
|
||||
QMap<int32, int32> msgsIds;
|
||||
for (int32 i = 0, l = v.size(); i < l; ++i) {
|
||||
const MTPMessage &msg(v.at(i));
|
||||
switch (msg.type()) {
|
||||
case mtpc_message: msgsIds.insert(msg.c_message().vid.v, i); break;
|
||||
case mtpc_message: {
|
||||
const MTPDmessage &d(msg.c_message());
|
||||
msgsIds.insert(d.vid.v, i);
|
||||
if (msgsState == 1) { // new message, index my forwarded messages to links overview
|
||||
checkEntitiesUpdate(d);
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageEmpty: msgsIds.insert(msg.c_messageEmpty().vid.v, i); break;
|
||||
case mtpc_messageService: msgsIds.insert(msg.c_messageService().vid.v, i); break;
|
||||
}
|
||||
@ -1072,11 +1078,11 @@ namespace App {
|
||||
}
|
||||
|
||||
WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert) {
|
||||
return App::webPageSet(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), webpage.has_site_name() ? qs(webpage.vsite_name) : QString(), webpage.has_title() ? qs(webpage.vtitle) : QString(), webpage.has_description() ? qs(webpage.vdescription) : QString(), webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : 0, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0);
|
||||
return App::webPageSet(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), webpage.has_site_name() ? qs(webpage.vsite_name) : QString(), webpage.has_title() ? qs(webpage.vtitle) : QString(), webpage.has_description() ? qs(webpage.vdescription) : QString(), webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : 0, webpage.has_document() ? App::feedDocument(webpage.vdocument) : 0, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0);
|
||||
}
|
||||
|
||||
WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert) {
|
||||
return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), QString(), 0, 0, QString(), webpage.vdate.v);
|
||||
return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), QString(), 0, 0, 0, QString(), webpage.vdate.v);
|
||||
}
|
||||
|
||||
WebPageData *feedWebPage(const MTPWebPage &webpage) {
|
||||
@ -1430,7 +1436,7 @@ namespace App {
|
||||
return i.value();
|
||||
}
|
||||
|
||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, int32 duration, const QString &author, int32 pendingTill) {
|
||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill) {
|
||||
if (convert) {
|
||||
if (convert->id != webPage) {
|
||||
WebPagesData::iterator i = webPagesData.find(convert->id);
|
||||
@ -1447,6 +1453,7 @@ namespace App {
|
||||
convert->title = title;
|
||||
convert->description = description;
|
||||
convert->photo = photo;
|
||||
convert->doc = doc;
|
||||
convert->duration = duration;
|
||||
convert->author = author;
|
||||
if (convert->pendingTill > 0 && pendingTill <= 0 && api()) api()->clearWebPageRequest(convert);
|
||||
@ -1460,7 +1467,7 @@ namespace App {
|
||||
if (convert) {
|
||||
result = convert;
|
||||
} else {
|
||||
result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, photo, duration, author, (pendingTill >= -1) ? pendingTill : -1);
|
||||
result = new WebPageData(webPage, toWebPageType(type), url, displayUrl, siteName, title, description, photo, doc, duration, author, (pendingTill >= -1) ? pendingTill : -1);
|
||||
if (pendingTill > 0 && api()) {
|
||||
api()->requestWebPageDelayed(result);
|
||||
}
|
||||
@ -1477,6 +1484,7 @@ namespace App {
|
||||
result->title = title;
|
||||
result->description = description;
|
||||
result->photo = photo;
|
||||
result->doc = doc;
|
||||
result->duration = duration;
|
||||
result->author = author;
|
||||
if (result->pendingTill > 0 && pendingTill <= 0 && api()) api()->clearWebPageRequest(result);
|
||||
@ -1681,6 +1689,7 @@ namespace App {
|
||||
void historyClearItems() {
|
||||
historyClearMsgs();
|
||||
randomData.clear();
|
||||
sentTextData.clear();
|
||||
mutedPeers.clear();
|
||||
updatedPeers.clear();
|
||||
cSetSavedPeers(SavedPeers());
|
||||
@ -1719,6 +1728,7 @@ namespace App {
|
||||
::audioItems.clear();
|
||||
::documentItems.clear();
|
||||
::webPageItems.clear();
|
||||
::sharedContactPhones.clear();
|
||||
::repliesTo.clear();
|
||||
lastPhotos.clear();
|
||||
lastPhotosMap.clear();
|
||||
@ -1756,6 +1766,18 @@ namespace App {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void historyRegSentText(uint64 randomId, const QString &text) {
|
||||
sentTextData.insert(randomId, text);
|
||||
}
|
||||
|
||||
void historyUnregSentText(uint64 randomId) {
|
||||
sentTextData.remove(randomId);
|
||||
}
|
||||
|
||||
QString histSentTextByItem(uint64 randomId) {
|
||||
return sentTextData.value(randomId);
|
||||
}
|
||||
|
||||
void prepareCorners(RoundCorners index, int32 radius, const style::color &color, const style::color *shadow = 0, QImage *cors = 0) {
|
||||
int32 r = radius * cIntRetinaFactor(), s = st::msgShadow * cIntRetinaFactor();
|
||||
QImage rect(r * 3, r * 3 + (shadow ? s : 0), QImage::Format_ARGB32_Premultiplied), localCors[4];
|
||||
@ -1827,6 +1849,12 @@ namespace App {
|
||||
prepareCorners(BotKeyboardCorners, st::msgRadius, st::botKbBg);
|
||||
prepareCorners(BotKeyboardOverCorners, st::msgRadius, st::botKbOverBg);
|
||||
prepareCorners(BotKeyboardDownCorners, st::msgRadius, st::botKbDownBg);
|
||||
prepareCorners(PhotoSelectOverlayCorners, st::msgRadius, st::overviewPhotoSelectOverlay);
|
||||
|
||||
prepareCorners(DocRedCorners, st::msgRadius, st::mvDocRedColor);
|
||||
prepareCorners(DocYellowCorners, st::msgRadius, st::mvDocYellowColor);
|
||||
prepareCorners(DocGreenCorners, st::msgRadius, st::mvDocGreenColor);
|
||||
prepareCorners(DocBlueCorners, st::msgRadius, st::mvDocBlueColor);
|
||||
|
||||
prepareCorners(MessageInCorners, st::msgRadius, st::msgInBg, &st::msgInShadow);
|
||||
prepareCorners(MessageInSelectedCorners, st::msgRadius, st::msgInSelectBg, &st::msgInSelectShadow);
|
||||
@ -2093,6 +2121,14 @@ namespace App {
|
||||
return ::webPageItems;
|
||||
}
|
||||
|
||||
void regSharedContactPhone(int32 userId, const QString &phone) {
|
||||
::sharedContactPhones[userId] = phone;
|
||||
}
|
||||
|
||||
QString phoneFromSharedContact(int32 userId) {
|
||||
return ::sharedContactPhones.value(userId);
|
||||
}
|
||||
|
||||
void regMuted(PeerData *peer, int32 changeIn) {
|
||||
::mutedPeers.insert(peer, true);
|
||||
if (App::main()) App::main()->updateMutedIn(changeIn);
|
||||
|
@ -58,6 +58,12 @@ enum RoundCorners {
|
||||
BotKeyboardCorners,
|
||||
BotKeyboardOverCorners,
|
||||
BotKeyboardDownCorners,
|
||||
PhotoSelectOverlayCorners,
|
||||
|
||||
DocRedCorners,
|
||||
DocYellowCorners,
|
||||
DocGreenCorners,
|
||||
DocBlueCorners,
|
||||
|
||||
InShadowCorners, // for photos without bg
|
||||
InSelectedShadowCorners,
|
||||
@ -112,6 +118,7 @@ namespace App {
|
||||
void feedParticipants(const MTPChatParticipants &p, bool requestBotInfos, bool emitPeerUpdated = true);
|
||||
void feedParticipantAdd(const MTPDupdateChatParticipantAdd &d, bool emitPeerUpdated = true);
|
||||
void feedParticipantDelete(const MTPDupdateChatParticipantDelete &d, bool emitPeerUpdated = true);
|
||||
void checkEntitiesUpdate(const MTPDmessage &m);
|
||||
void feedMsgs(const MTPVector<MTPMessage> &msgs, int msgsState = 0); // 2 - new read message, 1 - new unread message, 0 - not new message, -1 - searched message
|
||||
void feedWereRead(const QVector<MTPint> &msgsIds);
|
||||
void feedInboxRead(const PeerId &peer, int32 upTo);
|
||||
@ -166,7 +173,7 @@ namespace App {
|
||||
DocumentData *document(const DocumentId &document);
|
||||
DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 date, const QVector<MTPDocumentAttribute> &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation);
|
||||
WebPageData *webPage(const WebPageId &webPage);
|
||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, int32 duration, const QString &author, int32 pendingTill);
|
||||
WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill);
|
||||
ImageLinkData *imageLink(const QString &imageLink);
|
||||
ImageLinkData *imageLinkSet(const QString &imageLink, ImageLinkType type, const QString &url);
|
||||
void forgetMedia();
|
||||
@ -188,6 +195,9 @@ namespace App {
|
||||
void historyRegRandom(uint64 randomId, MsgId itemId);
|
||||
void historyUnregRandom(uint64 randomId);
|
||||
MsgId histItemByRandom(uint64 randomId);
|
||||
void historyRegSentText(uint64 itemId, const QString &text);
|
||||
void historyUnregSentText(uint64 itemId);
|
||||
QString histSentTextByItem(uint64 itemId);
|
||||
|
||||
void hoveredItem(HistoryItem *item);
|
||||
HistoryItem *hoveredItem();
|
||||
@ -238,6 +248,9 @@ namespace App {
|
||||
void unregWebPageItem(WebPageData *data, HistoryItem *item);
|
||||
const WebPageItems &webPageItems();
|
||||
|
||||
void regSharedContactPhone(int32 userId, const QString &phone);
|
||||
QString phoneFromSharedContact(int32 userId);
|
||||
|
||||
void regMuted(PeerData *peer, int32 changeIn);
|
||||
void unregMuted(PeerData *peer);
|
||||
void updateMuted();
|
||||
|
@ -95,7 +95,10 @@ namespace {
|
||||
|
||||
Application::Application(int &argc, char **argv) : PsApplication(argc, argv),
|
||||
serverName(psServerPrefix() + cGUIDStr()), closing(false),
|
||||
updateRequestId(0), updateReply(0), updateThread(0), updateDownloader(0), _translator(0) {
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
updateRequestId(0), updateReply(0), updateThread(0), updateDownloader(0),
|
||||
#endif
|
||||
_translator(0) {
|
||||
|
||||
DEBUG_LOG(("Application Info: creation.."));
|
||||
|
||||
@ -178,9 +181,11 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv),
|
||||
connect(&socket, SIGNAL(readyRead()), this, SLOT(socketReading()));
|
||||
connect(&server, SIGNAL(newConnection()), this, SLOT(newInstanceConnected()));
|
||||
connect(this, SIGNAL(aboutToQuit()), this, SLOT(closeApplication()));
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
connect(&updateCheckTimer, SIGNAL(timeout()), this, SLOT(startUpdateCheck()));
|
||||
connect(this, SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
|
||||
connect(this, SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
|
||||
#endif
|
||||
connect(this, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(onAppStateChanged(Qt::ApplicationState)));
|
||||
//connect(&writeUserConfigTimer, SIGNAL(timeout()), this, SLOT(onWriteUserConfig()));
|
||||
//writeUserConfigTimer.setSingleShot(true);
|
||||
@ -195,6 +200,7 @@ Application::Application(int &argc, char **argv) : PsApplication(argc, argv),
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void Application::updateGotCurrent() {
|
||||
if (!updateReply || updateThread) return;
|
||||
|
||||
@ -258,6 +264,7 @@ void Application::onUpdateFailed() {
|
||||
cSetLastUpdateCheck(unixtime());
|
||||
Local::writeSettings();
|
||||
}
|
||||
#endif
|
||||
|
||||
void Application::regPhotoUpdate(const PeerId &peer, MsgId msgId) {
|
||||
photoUpdates.insert(msgId, peer);
|
||||
@ -431,11 +438,16 @@ void Application::onSwitchTestMode() {
|
||||
}
|
||||
|
||||
Application::UpdatingState Application::updatingState() {
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (!updateThread) return Application::UpdatingNone;
|
||||
if (!updateDownloader) return Application::UpdatingReady;
|
||||
return Application::UpdatingDownload;
|
||||
#else
|
||||
return Application::UpdatingNone;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
int32 Application::updatingSize() {
|
||||
if (!updateDownloader) return 0;
|
||||
return updateDownloader->size();
|
||||
@ -445,6 +457,7 @@ int32 Application::updatingReady() {
|
||||
if (!updateDownloader) return 0;
|
||||
return updateDownloader->ready();
|
||||
}
|
||||
#endif
|
||||
|
||||
FileUploader *Application::uploader() {
|
||||
if (!::uploader) ::uploader = new FileUploader();
|
||||
@ -488,6 +501,7 @@ void Application::uploadProfilePhoto(const QImage &tosend, const PeerId &peerId)
|
||||
App::uploader()->uploadMedia(newId, ready);
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void Application::stopUpdate() {
|
||||
if (updateReply) {
|
||||
updateReply->abort();
|
||||
@ -541,6 +555,7 @@ void Application::startUpdateCheck(bool forceWait) {
|
||||
updateCheckTimer.start((updateInSecs + 5) * 1000);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
QChar _toHex(ushort v) {
|
||||
@ -643,11 +658,13 @@ void Application::socketError(QLocalSocket::LocalSocketError e) {
|
||||
return App::quit();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (!cNoStartUpdate() && checkReadyUpdate()) {
|
||||
cSetRestartingUpdate(true);
|
||||
DEBUG_LOG(("Application Info: installing update instead of starting app.."));
|
||||
return App::quit();
|
||||
}
|
||||
#endif
|
||||
|
||||
startApp();
|
||||
}
|
||||
@ -656,9 +673,9 @@ void Application::checkMapVersion() {
|
||||
if (Local::oldMapVersion() < AppVersion) {
|
||||
if (Local::oldMapVersion()) {
|
||||
QString versionFeatures;
|
||||
if (cDevVersion() && Local::oldMapVersion() < 8050) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Bug fixes in Windows notifications\n\xe2\x80\x94 Fixed input methods on Linux (Fcitx and IBus)");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!cDevVersion() && Local::oldMapVersion() < 8051) {
|
||||
if (cDevVersion() && Local::oldMapVersion() < 8054) {
|
||||
versionFeatures = QString::fromUtf8("\xe2\x80\x94 Preview when sending links to GIF animations and PDF files\n\xe2\x80\x94 Full date and time shown when mouse over message timestamp");// .replace('@', qsl("@") + QChar(0x200D));
|
||||
} else if (!cDevVersion() && Local::oldMapVersion() < 8055) {
|
||||
versionFeatures = lang(lng_new_version_text).trimmed();
|
||||
}
|
||||
if (!versionFeatures.isEmpty()) {
|
||||
@ -833,13 +850,15 @@ Application::~Application() {
|
||||
App::deinitMedia();
|
||||
deinitImageLinkManager();
|
||||
mainApp = 0;
|
||||
delete updateReply;
|
||||
delete ::uploader;
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
delete updateReply;
|
||||
updateReply = 0;
|
||||
if (updateDownloader) updateDownloader->deleteLater();
|
||||
updateDownloader = 0;
|
||||
if (updateThread) updateThread->quit();
|
||||
updateThread = 0;
|
||||
#endif
|
||||
|
||||
delete window;
|
||||
|
||||
|
@ -49,8 +49,10 @@ public:
|
||||
UpdatingReady,
|
||||
};
|
||||
UpdatingState updatingState();
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
int32 updatingSize();
|
||||
int32 updatingReady();
|
||||
#endif
|
||||
|
||||
FileUploader *uploader();
|
||||
void uploadProfilePhoto(const QImage &tosend, const PeerId &peerId);
|
||||
@ -78,11 +80,13 @@ public:
|
||||
|
||||
signals:
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void updateChecking();
|
||||
void updateLatest();
|
||||
void updateDownloading(qint64 ready, qint64 total);
|
||||
void updateReady();
|
||||
void updateFailed();
|
||||
#endif
|
||||
|
||||
void peerPhotoDone(PeerId peer);
|
||||
void peerPhotoFail(PeerId peer);
|
||||
@ -91,7 +95,9 @@ signals:
|
||||
|
||||
public slots:
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void startUpdateCheck(bool forceWait = false);
|
||||
#endif
|
||||
void socketConnected();
|
||||
void socketError(QLocalSocket::LocalSocketError e);
|
||||
void socketDisconnected();
|
||||
@ -103,11 +109,13 @@ public slots:
|
||||
void readClients();
|
||||
void removeClients();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void updateGotCurrent();
|
||||
void updateFailedCurrent(QNetworkReply::NetworkError e);
|
||||
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
#endif
|
||||
|
||||
void photoUpdated(MsgId msgId, const MTPInputFile &file);
|
||||
|
||||
@ -142,12 +150,14 @@ private:
|
||||
|
||||
Window *window;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
mtpRequestId updateRequestId;
|
||||
QNetworkAccessManager updateManager;
|
||||
QNetworkReply *updateReply;
|
||||
SingleTimer updateCheckTimer;
|
||||
QThread *updateThread;
|
||||
UpdateDownloader *updateDownloader;
|
||||
#endif
|
||||
|
||||
QTimer writeUserConfigTimer;
|
||||
|
||||
|
Binary file not shown.
Before ![]() (image error) Size: 167 KiB After ![]() (image error) Size: 168 KiB ![]() ![]() |
Binary file not shown.
Before ![]() (image error) Size: 220 KiB After ![]() (image error) Size: 222 KiB ![]() ![]() |
@ -15,11 +15,14 @@ GNU General Public License for more details.
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "application.h"
|
||||
#include "pspecific.h"
|
||||
#include "autoupdater.h"
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
typedef DWORD VerInt;
|
||||
typedef WCHAR VerChar;
|
||||
@ -534,3 +537,5 @@ bool checkReadyUpdate() {
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -17,6 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
|
||||
#include <QtNetwork/QLocalSocket>
|
||||
#include <QtNetwork/QLocalServer>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
@ -60,3 +62,5 @@ private:
|
||||
};
|
||||
|
||||
bool checkReadyUpdate();
|
||||
|
||||
#endif
|
||||
|
@ -285,7 +285,6 @@ void AddContactBox::onImportDone(const MTPcontacts_ImportedContacts &res) {
|
||||
}
|
||||
if (uid) {
|
||||
App::main()->addNewContact(uid);
|
||||
App::main()->choosePeer(App::peerFromUser(uid), ShowAtUnreadMsgId);
|
||||
App::wnd()->hideLayer();
|
||||
} else {
|
||||
_addButton.hide();
|
||||
|
@ -1271,6 +1271,8 @@ void CreateGroupBox::created(const MTPUpdates &updates) {
|
||||
} break;
|
||||
case mtpc_updateShortChatMessage: {
|
||||
} break;
|
||||
case mtpc_updateShortSentMessage: {
|
||||
} break;
|
||||
case mtpc_updatesTooLong: {
|
||||
} break;
|
||||
}
|
||||
|
@ -17,8 +17,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
static const int32 AppVersion = 8051;
|
||||
static const wchar_t *AppVersionStr = L"0.8.51";
|
||||
static const int32 AppVersion = 8055;
|
||||
static const wchar_t *AppVersionStr = L"0.8.55";
|
||||
static const bool DevVersion = false;
|
||||
|
||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||
@ -81,6 +81,7 @@ enum {
|
||||
AutoSearchTimeout = 900, // 0.9 secs
|
||||
SearchPerPage = 50,
|
||||
SearchManyPerPage = 100,
|
||||
LinksOverviewPerPage = 12,
|
||||
MediaOverviewStartPerPage = 5,
|
||||
MediaOverviewPreloadCount = 4,
|
||||
|
||||
|
@ -829,22 +829,17 @@ void DialogsListWidget::contactsReceived(const QVector<MTPContact> &contacts) {
|
||||
refresh();
|
||||
}
|
||||
|
||||
int32 DialogsListWidget::addNewContact(int32 uid, bool select) {
|
||||
int32 DialogsListWidget::addNewContact(int32 uid, bool select) { // -2 - err, -1 - don't scroll, >= 0 - scroll
|
||||
PeerId peer = App::peerFromUser(uid);
|
||||
if (!App::peerLoaded(peer)) return -1;
|
||||
if (!App::peerLoaded(peer)) return -2;
|
||||
|
||||
History *history = App::history(peer);
|
||||
contacts.addByName(history);
|
||||
DialogsList::RowByPeer::const_iterator i = dialogs.list.rowByPeer.constFind(peer);
|
||||
if (i == dialogs.list.rowByPeer.cend()) {
|
||||
DialogRow *added = contactsNoDialogs.addByName(history);
|
||||
if (!added) return -1;
|
||||
if (select && false) {
|
||||
sel = added;
|
||||
contactSel = true;
|
||||
}
|
||||
// if (contactsNoDialogs.list.count == 1 && !dialogs.list.count) refresh();
|
||||
return added ? ((dialogs.list.count + added->pos) * st::dlgHeight) : -1;
|
||||
if (!added) return -2;
|
||||
return -1;
|
||||
}
|
||||
if (select) {
|
||||
sel = i.value();
|
||||
@ -1700,7 +1695,6 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void DialogsWidget::onNeedSearchMessages() {
|
||||
if (!onSearchMessages(true)) {
|
||||
_searchTimer.start(AutoSearchTimeout);
|
||||
@ -1843,9 +1837,9 @@ bool DialogsWidget::addNewContact(int32 uid, bool show) {
|
||||
_filter.setText(QString());
|
||||
onFilterUpdate();
|
||||
int32 to = list.addNewContact(uid, true);
|
||||
if (to < 0 || !show) return false;
|
||||
if (to < -1 || !show) return false;
|
||||
list.refresh();
|
||||
scroll.scrollToY(to);
|
||||
if (to >= 0) scroll.scrollToY(to);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
void activate();
|
||||
|
||||
void contactsReceived(const QVector<MTPContact> &contacts);
|
||||
int32 addNewContact(int32 uid, bool sel = false); // return y of row or -1 if failed
|
||||
int32 addNewContact(int32 uid, bool sel = false); // -2 - err, -1 - don't scroll, >= 0 - scroll
|
||||
|
||||
int32 filteredOffset() const;
|
||||
int32 peopleOffset() const;
|
||||
|
@ -146,8 +146,8 @@ inline bool emojiEdge(const QChar *ch) {
|
||||
|
||||
inline QString replaceEmojis(const QString &text) {
|
||||
QString result;
|
||||
LinkRanges lnkRanges = textParseLinks(text, TextParseLinks | TextParseMentions | TextParseHashtags);
|
||||
int32 currentLink = 0, lnkCount = lnkRanges.size();
|
||||
LinksInText links = textParseLinks(text, TextParseLinks | TextParseMentions | TextParseHashtags);
|
||||
int32 currentLink = 0, lnkCount = links.size();
|
||||
const QChar *emojiStart = text.unicode(), *emojiEnd = emojiStart, *e = text.cend();
|
||||
bool canFindEmoji = true, consumePrevious = false;
|
||||
for (const QChar *ch = emojiEnd; ch != e;) {
|
||||
@ -157,14 +157,14 @@ inline QString replaceEmojis(const QString &text) {
|
||||
emojiFind(ch, e, newEmojiEnd, emojiCode);
|
||||
}
|
||||
|
||||
while (currentLink < lnkCount && ch >= lnkRanges[currentLink].from + lnkRanges[currentLink].len) {
|
||||
while (currentLink < lnkCount && ch >= emojiStart + links[currentLink].offset + links[currentLink].length) {
|
||||
++currentLink;
|
||||
}
|
||||
EmojiPtr emoji = emojiCode ? emojiGet(emojiCode) : 0;
|
||||
if (emoji && emoji != TwoSymbolEmoji &&
|
||||
(ch == emojiStart || !ch->isLetterOrNumber() || !(ch - 1)->isLetterOrNumber()) &&
|
||||
(newEmojiEnd == e || !newEmojiEnd->isLetterOrNumber() || newEmojiEnd == emojiStart || !(newEmojiEnd - 1)->isLetterOrNumber()) &&
|
||||
(currentLink >= lnkCount || (ch < lnkRanges[currentLink].from && newEmojiEnd <= lnkRanges[currentLink].from) || (ch >= lnkRanges[currentLink].from + lnkRanges[currentLink].len && newEmojiEnd > lnkRanges[currentLink].from + lnkRanges[currentLink].len))
|
||||
(currentLink >= lnkCount || (ch < emojiStart + links[currentLink].offset && newEmojiEnd <= emojiStart + links[currentLink].offset) || (ch >= emojiStart + links[currentLink].offset + links[currentLink].length && newEmojiEnd > emojiStart + links[currentLink].offset + links[currentLink].length))
|
||||
) {
|
||||
// if (newEmojiEnd < e && newEmojiEnd->unicode() == ' ') ++newEmojiEnd;
|
||||
if (result.isEmpty()) result.reserve(text.size());
|
||||
|
@ -24,7 +24,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
FlatTextarea::FlatTextarea(QWidget *parent, const style::flatTextarea &st, const QString &pholder, const QString &v) : QTextEdit(v, parent),
|
||||
_ph(pholder), _oldtext(v), _phVisible(!v.length()),
|
||||
a_phLeft(_phVisible ? 0 : st.phShift), a_phAlpha(_phVisible ? 1 : 0), a_phColor(st.phColor->c),
|
||||
_st(st), _undoAvailable(false), _redoAvailable(false), _fakeMargin(0),
|
||||
_st(st), _undoAvailable(false), _redoAvailable(false), _inDrop(false), _fakeMargin(0),
|
||||
_touchPress(false), _touchRightButton(false), _touchMove(false), _replacingEmojis(false) {
|
||||
setAcceptRichText(false);
|
||||
resize(_st.width, _st.font->height);
|
||||
@ -530,7 +530,7 @@ QStringList FlatTextarea::linksList() const {
|
||||
|
||||
void FlatTextarea::insertFromMimeData(const QMimeData *source) {
|
||||
QTextEdit::insertFromMimeData(source);
|
||||
emit spacedReturnedPasted();
|
||||
if (!_inDrop) emit spacedReturnedPasted();
|
||||
}
|
||||
|
||||
void FlatTextarea::insertEmoji(EmojiPtr emoji, QTextCursor c) {
|
||||
@ -814,3 +814,14 @@ void FlatTextarea::resizeEvent(QResizeEvent *e) {
|
||||
_phelided = _st.font->m.elidedText(_ph, Qt::ElideRight, width() - _st.textMrg.left() - _st.textMrg.right() - _st.phPos.x() - 1);
|
||||
QTextEdit::resizeEvent(e);
|
||||
}
|
||||
|
||||
void FlatTextarea::mousePressEvent(QMouseEvent *e) {
|
||||
QTextEdit::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void FlatTextarea::dropEvent(QDropEvent *e) {
|
||||
_inDrop = true;
|
||||
QTextEdit::dropEvent(e);
|
||||
_inDrop = false;
|
||||
emit spacedReturnedPasted();
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ public:
|
||||
void focusOutEvent(QFocusEvent *e);
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void resizeEvent(QResizeEvent *e);
|
||||
void mousePressEvent(QMouseEvent *e);
|
||||
void dropEvent(QDropEvent *e);
|
||||
|
||||
const QString &getLastText() const;
|
||||
void updatePlaceholder();
|
||||
@ -118,7 +120,7 @@ private:
|
||||
anim::cvalue a_phColor;
|
||||
style::flatTextarea _st;
|
||||
|
||||
bool _undoAvailable, _redoAvailable;
|
||||
bool _undoAvailable, _redoAvailable, _inDrop;
|
||||
|
||||
int32 _fakeMargin;
|
||||
|
||||
|
@ -20,6 +20,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
#include "pspecific.h"
|
||||
|
||||
#include <private/qharfbuzz_p.h>
|
||||
|
||||
namespace {
|
||||
@ -328,13 +330,13 @@ public:
|
||||
}
|
||||
|
||||
bool checkWaitedLink() {
|
||||
if (waitingLink == linksEnd || ptr < waitingLink->from || links.size() >= 0x7FFF) {
|
||||
if (waitingLink == linksEnd || ptr < start + waitingLink->offset || links.size() >= 0x7FFF) {
|
||||
return true;
|
||||
}
|
||||
|
||||
createBlock();
|
||||
|
||||
QString lnkUrl = QString(waitingLink->from, waitingLink->len), lnkText;
|
||||
QString lnkUrl = QString(start + waitingLink->offset, waitingLink->length), lnkText;
|
||||
int32 fullDisplayed;
|
||||
getLinkData(lnkUrl, lnkText, fullDisplayed);
|
||||
|
||||
@ -342,7 +344,7 @@ public:
|
||||
lnkIndex = 0x8000 + links.size();
|
||||
|
||||
_t->_text += lnkText;
|
||||
ptr = waitingLink->from + waitingLink->len;
|
||||
ptr = start + waitingLink->offset + waitingLink->length;
|
||||
|
||||
createBlock();
|
||||
++waitingLink;
|
||||
@ -519,8 +521,51 @@ public:
|
||||
emoji = e;
|
||||
}
|
||||
|
||||
TextParser(Text *t, const QString &text, const TextParseOptions &options) : _t(t), src(text),
|
||||
rich(options.flags & TextParseRichText), multiline(options.flags & TextParseMultiline), maxLnkIndex(0), flags(0), lnkIndex(0), stopAfterWidth(QFIXED_MAX) {
|
||||
TextParser(Text *t, const QString &text, const TextParseOptions &options) : _t(t),
|
||||
src(text),
|
||||
rich(options.flags & TextParseRichText),
|
||||
multiline(options.flags & TextParseMultiline),
|
||||
maxLnkIndex(0),
|
||||
flags(0),
|
||||
lnkIndex(0),
|
||||
stopAfterWidth(QFIXED_MAX) {
|
||||
if (options.flags & TextParseLinks) {
|
||||
lnkRanges = textParseLinks(src, options.flags, rich);
|
||||
}
|
||||
parse(options);
|
||||
}
|
||||
TextParser(Text *t, const QString &text, const LinksInText &links, const TextParseOptions &options) : _t(t),
|
||||
src(text),
|
||||
rich(options.flags & TextParseRichText),
|
||||
multiline(options.flags & TextParseMultiline),
|
||||
maxLnkIndex(0),
|
||||
flags(0),
|
||||
lnkIndex(0),
|
||||
stopAfterWidth(QFIXED_MAX) {
|
||||
if ((options.flags & TextParseLinks) && !links.isEmpty()) {
|
||||
bool parseMentions = (options.flags & TextParseMentions);
|
||||
bool parseHashtags = (options.flags & TextParseHashtags);
|
||||
bool parseBotCommands = (options.flags & TextParseBotCommands);
|
||||
if (parseMentions && parseHashtags && parseBotCommands) {
|
||||
lnkRanges = links;
|
||||
} else {
|
||||
int32 i = 0, l = links.size();
|
||||
lnkRanges.reserve(l);
|
||||
const QChar *p = text.constData(), s = text.size();
|
||||
for (; i < l; ++i) {
|
||||
LinkInTextType t = links.at(i).type;
|
||||
if ((t == LinkInTextMention && !parseMentions) ||
|
||||
(t == LinkInTextHashtag && !parseHashtags) ||
|
||||
(t == LinkInTextBotCommand && !parseBotCommands)) {
|
||||
continue;
|
||||
}
|
||||
lnkRanges.push_back(links.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
parse(options);
|
||||
}
|
||||
void parse(const TextParseOptions &options) {
|
||||
int flags = options.flags;
|
||||
if (options.maxw > 0 && options.maxh > 0) {
|
||||
stopAfterWidth = ((options.maxh / _t->_font->height) + 1) * options.maxw;
|
||||
@ -529,19 +574,16 @@ public:
|
||||
start = src.constData();
|
||||
end = start + src.size();
|
||||
|
||||
if (options.flags & TextParseLinks) {
|
||||
lnkRanges = textParseLinks(src, options.flags, rich);
|
||||
ptr = start;
|
||||
while (ptr != end && chIsTrimmed(*ptr, rich)) {
|
||||
++ptr;
|
||||
}
|
||||
|
||||
while (start != end && chIsTrimmed(*start, rich)) {
|
||||
++start;
|
||||
}
|
||||
while (start != end && chIsTrimmed(*(end - 1), rich)) {
|
||||
while (ptr != end && chIsTrimmed(*(end - 1), rich)) {
|
||||
--end;
|
||||
}
|
||||
|
||||
_t->_text.resize(0);
|
||||
_t->_text.reserve(end - start);
|
||||
_t->_text.reserve(end - ptr);
|
||||
|
||||
diacs = 0;
|
||||
sumWidth = 0;
|
||||
@ -552,9 +594,9 @@ public:
|
||||
ch = chInt = 0;
|
||||
lastSkipped = false;
|
||||
lastSpace = true;
|
||||
waitingLink = lnkRanges.isEmpty() ? 0 : lnkRanges.constData();
|
||||
linksEnd = lnkRanges.isEmpty() ? 0 : waitingLink + lnkRanges.size();
|
||||
for (ptr = start; ptr <= end; ++ptr) {
|
||||
waitingLink = lnkRanges.cbegin();
|
||||
linksEnd = lnkRanges.cend();
|
||||
for (; ptr <= end; ++ptr) {
|
||||
if (!checkWaitedLink()) {
|
||||
break;
|
||||
}
|
||||
@ -615,8 +657,8 @@ private:
|
||||
const QChar *start, *end, *ptr;
|
||||
bool rich, multiline;
|
||||
|
||||
LinkRanges lnkRanges;
|
||||
const LinkRange *waitingLink, *linksEnd;
|
||||
LinksInText lnkRanges;
|
||||
LinksInText::const_iterator waitingLink, linksEnd;
|
||||
|
||||
struct TextLinkData {
|
||||
TextLinkData(const QString &url = QString(), int32 fullDisplayed = 1) : url(url), fullDisplayed(fullDisplayed) {
|
||||
@ -769,6 +811,15 @@ void TextLink::onClick(Qt::MouseButton button) const {
|
||||
}
|
||||
}
|
||||
|
||||
void EmailLink::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
QUrl url(qstr("mailto:") + _email);
|
||||
if (!QDesktopServices::openUrl(url)) {
|
||||
psOpenFile(url.toString(QUrl::FullyEncoded), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MentionLink::onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
App::openUserByName(_tag.mid(1), true);
|
||||
@ -2299,9 +2350,13 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||
{
|
||||
TextParser parser(this, text, options);
|
||||
}
|
||||
recountNaturalSize(true, options.dir);
|
||||
}
|
||||
|
||||
void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
|
||||
NewlineBlock *lastNewline = 0;
|
||||
|
||||
_maxWidth = _minHeight = 0;
|
||||
int32 lineHeight = 0;
|
||||
int32 result = 0, lastNewlineStart = 0;
|
||||
QFixed _width = 0, last_rBearing = 0, last_rPadding = 0;
|
||||
@ -2313,14 +2368,16 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||
|
||||
if (_btype == TextBlockNewline) {
|
||||
if (!lineHeight) lineHeight = blockHeight;
|
||||
Qt::LayoutDirection dir = options.dir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
if (initial) {
|
||||
Qt::LayoutDirection dir = optionsDir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
}
|
||||
}
|
||||
lastNewlineStart = b->from();
|
||||
lastNewline = static_cast<NewlineBlock*>(b);
|
||||
@ -2344,14 +2401,16 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||
last_rPadding = b->f_rpadding();
|
||||
continue;
|
||||
}
|
||||
Qt::LayoutDirection dir = options.dir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
if (initial) {
|
||||
Qt::LayoutDirection dir = optionsDir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
}
|
||||
}
|
||||
if (_width > 0) {
|
||||
if (!lineHeight) lineHeight = _blockHeight(_blocks.back(), _font);
|
||||
@ -2362,6 +2421,16 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||
}
|
||||
}
|
||||
|
||||
void Text::setMarkedText(style::font font, const QString &text, const LinksInText &links, const TextParseOptions &options) {
|
||||
if (!_textStyle) _initDefault();
|
||||
_font = font;
|
||||
clean();
|
||||
{
|
||||
TextParser parser(this, text, links, options);
|
||||
}
|
||||
recountNaturalSize(true, options.dir);
|
||||
}
|
||||
|
||||
void Text::setRichText(style::font font, const QString &text, TextParseOptions options, const TextCustomTagsMap &custom) {
|
||||
QString parsed;
|
||||
parsed.reserve(text.size());
|
||||
@ -2449,6 +2518,82 @@ bool Text::hasLinks() const {
|
||||
return !_links.isEmpty();
|
||||
}
|
||||
|
||||
void Text::setSkipBlock(int32 width, int32 height) {
|
||||
if (!_blocks.isEmpty() && _blocks.back()->type() == TextBlockSkip) {
|
||||
SkipBlock *block = static_cast<SkipBlock*>(_blocks.back());
|
||||
if (block->width() == width && block->height() == height) return;
|
||||
_text.resize(block->from());
|
||||
_blocks.pop_back();
|
||||
}
|
||||
_text.push_back('_');
|
||||
_blocks.push_back(new SkipBlock(_font, _text, _text.size() - 1, width, height, 0));
|
||||
recountNaturalSize(false);
|
||||
}
|
||||
|
||||
void Text::removeSkipBlock() {
|
||||
if (!_blocks.isEmpty() && _blocks.back()->type() == TextBlockSkip) {
|
||||
_text.resize(_blocks.back()->from());
|
||||
_blocks.pop_back();
|
||||
recountNaturalSize(false);
|
||||
}
|
||||
}
|
||||
|
||||
LinksInText Text::calcLinksInText() const {
|
||||
LinksInText result;
|
||||
int32 lnkFrom = 0, lnkIndex = 0, offset = 0;
|
||||
for (TextBlocks::const_iterator i = _blocks.cbegin(), e = _blocks.cend(); true; ++i) {
|
||||
int32 blockLnkIndex = (i == e) ? 0 : (*i)->lnkIndex();
|
||||
int32 blockFrom = (i == e) ? _text.size() : (*i)->from();
|
||||
if (blockLnkIndex != lnkIndex) {
|
||||
if (lnkIndex) { // write link
|
||||
const TextLinkPtr &lnk(_links.at(lnkIndex - 1));
|
||||
const QString &url(lnk ? lnk->text() : QString());
|
||||
|
||||
int32 rangeFrom = lnkFrom, rangeTo = blockFrom;
|
||||
if (rangeTo > rangeFrom) {
|
||||
QStringRef r = _text.midRef(rangeFrom, rangeTo - rangeFrom);
|
||||
if (url.isEmpty()) {
|
||||
offset += r.size();
|
||||
} else {
|
||||
QUrl u(url);
|
||||
if (r.size() <= 3 || _text.midRef(lnkFrom, r.size() - 3) == (u.isValid() ? u.toDisplayString() : url).midRef(0, r.size() - 3)) { // same link
|
||||
if (url.at(0) == '@') {
|
||||
result.push_back(LinkInText(LinkInTextMention, offset, url.size()));
|
||||
} else if (url.at(0) == '#') {
|
||||
result.push_back(LinkInText(LinkInTextHashtag, offset, url.size()));
|
||||
} else if (url.at(0) == '/') {
|
||||
result.push_back(LinkInText(LinkInTextBotCommand, offset, url.size()));
|
||||
} else if (url.indexOf('@') > 0 && url.indexOf('/') <= 0) {
|
||||
result.push_back(LinkInText(LinkInTextEmail, offset, url.size()));
|
||||
} else {
|
||||
result.push_back(LinkInText(LinkInTextUrl, offset, url.size()));
|
||||
}
|
||||
offset += url.size();
|
||||
} else {
|
||||
result.push_back(LinkInText(LinkInTextCustomUrl, offset, r.size(), url));
|
||||
offset += r.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lnkIndex = blockLnkIndex;
|
||||
lnkFrom = blockFrom;
|
||||
}
|
||||
if (i == e) break;
|
||||
|
||||
TextBlockType type = (*i)->type();
|
||||
if (type == TextBlockSkip) continue;
|
||||
|
||||
if (!blockLnkIndex) {
|
||||
int32 rangeFrom = (*i)->from(), rangeTo = uint16((*i)->from() + TextPainter::_blockLength(this, i, e));
|
||||
if (rangeTo > rangeFrom) {
|
||||
offset += rangeTo - rangeFrom;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int32 Text::countHeight(int32 w) const {
|
||||
QFixed width = w;
|
||||
if (width < _minResizeWidth) width = _minResizeWidth;
|
||||
@ -4035,16 +4180,16 @@ QString textSearchKey(const QString &text) {
|
||||
bool textSplit(QString &sendingText, QString &leftText, int32 limit) {
|
||||
if (leftText.isEmpty() || !limit) return false;
|
||||
|
||||
LinkRanges lnkRanges = textParseLinks(leftText, TextParseLinks | TextParseMentions | TextParseHashtags);
|
||||
int32 currentLink = 0, lnkCount = lnkRanges.size();
|
||||
LinksInText links = textParseLinks(leftText, TextParseLinks | TextParseMentions | TextParseHashtags);
|
||||
int32 currentLink = 0, lnkCount = links.size();
|
||||
|
||||
int32 s = 0, half = limit / 2, goodLevel = 0;
|
||||
for (const QChar *start = leftText.constData(), *ch = start, *end = leftText.constEnd(), *good = ch; ch != end; ++ch, ++s) {
|
||||
while (currentLink < lnkCount && ch >= lnkRanges[currentLink].from + lnkRanges[currentLink].len) {
|
||||
while (currentLink < lnkCount && ch >= start + links[currentLink].offset + links[currentLink].length) {
|
||||
++currentLink;
|
||||
}
|
||||
|
||||
bool inLink = (currentLink < lnkCount) && (ch > lnkRanges[currentLink].from) && (ch < lnkRanges[currentLink].from + lnkRanges[currentLink].len);
|
||||
bool inLink = (currentLink < lnkCount) && (ch > start + links[currentLink].offset) && (ch < start + links[currentLink].offset + links[currentLink].length);
|
||||
if (s > half) {
|
||||
if (inLink) {
|
||||
if (!goodLevel) good = ch;
|
||||
@ -4102,8 +4247,8 @@ bool textSplit(QString &sendingText, QString &leftText, int32 limit) {
|
||||
return true;
|
||||
}
|
||||
|
||||
LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some code is duplicated in flattextarea.cpp!
|
||||
LinkRanges lnkRanges;
|
||||
LinksInText textParseLinks(const QString &text, int32 flags, bool rich) { // some code is duplicated in flattextarea.cpp!
|
||||
LinksInText result;
|
||||
|
||||
bool withHashtags = (flags & TextParseHashtags);
|
||||
bool withMentions = (flags & TextParseMentions);
|
||||
@ -4126,7 +4271,8 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
||||
QRegularExpressionMatch mMention = withMentions ? _reMention.match(text, qMax(mentionSkip, matchOffset)) : QRegularExpressionMatch();
|
||||
QRegularExpressionMatch mBotCommand = withBotCommands ? _reBotCommand.match(text, matchOffset) : QRegularExpressionMatch();
|
||||
|
||||
LinkRange link;
|
||||
LinkInTextType lnkType = LinkInTextUrl;
|
||||
int32 lnkOffset = 0, lnkLength = 0;
|
||||
int32 domainOffset = mDomain.hasMatch() ? mDomain.capturedStart() : INT_MAX,
|
||||
domainEnd = mDomain.hasMatch() ? mDomain.capturedEnd() : INT_MAX,
|
||||
explicitDomainOffset = mExplicitDomain.hasMatch() ? mExplicitDomain.capturedStart() : INT_MAX,
|
||||
@ -4191,9 +4337,9 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
link.from = start + mentionOffset;
|
||||
link.len = start + mentionEnd - link.from;
|
||||
lnkType = LinkInTextMention;
|
||||
lnkOffset = mentionOffset;
|
||||
lnkLength = mentionEnd - mentionOffset;
|
||||
} else if (hashtagOffset < domainOffset && hashtagOffset < botCommandOffset) {
|
||||
if (hashtagOffset > nextCmd) {
|
||||
const QChar *after = textSkipCommand(start + nextCmd, start + len);
|
||||
@ -4203,8 +4349,9 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
||||
}
|
||||
}
|
||||
|
||||
link.from = start + hashtagOffset;
|
||||
link.len = start + hashtagEnd - link.from;
|
||||
lnkType = LinkInTextHashtag;
|
||||
lnkOffset = hashtagOffset;
|
||||
lnkLength = hashtagEnd - hashtagOffset;
|
||||
} else if (botCommandOffset < domainOffset) {
|
||||
if (botCommandOffset > nextCmd) {
|
||||
const QChar *after = textSkipCommand(start + nextCmd, start + len);
|
||||
@ -4214,8 +4361,9 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
||||
}
|
||||
}
|
||||
|
||||
link.from = start + botCommandOffset;
|
||||
link.len = start + botCommandEnd - link.from;
|
||||
lnkType = LinkInTextBotCommand;
|
||||
lnkOffset = botCommandOffset;
|
||||
lnkLength = botCommandEnd - botCommandOffset;
|
||||
} else {
|
||||
if (domainOffset > nextCmd) {
|
||||
const QChar *after = textSkipCommand(start + nextCmd, start + len);
|
||||
@ -4239,16 +4387,17 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
||||
if (mailOffset < offset) {
|
||||
mailOffset = offset;
|
||||
}
|
||||
link.from = start + mailOffset;
|
||||
link.len = domainEnd - mailOffset;
|
||||
lnkType = LinkInTextEmail;
|
||||
lnkOffset = mailOffset;
|
||||
lnkLength = domainEnd - mailOffset;
|
||||
}
|
||||
}
|
||||
if (!link.from || !link.len) {
|
||||
if (lnkType == LinkInTextUrl && !lnkLength) {
|
||||
if (!isProtocolValid || !isTopDomainValid) {
|
||||
matchOffset = domainEnd;
|
||||
continue;
|
||||
}
|
||||
link.from = start + domainOffset;
|
||||
lnkOffset = domainOffset;
|
||||
|
||||
QStack<const QChar*> parenth;
|
||||
const QChar *domainEnd = start + mDomain.capturedEnd(), *p = domainEnd;
|
||||
@ -4283,15 +4432,15 @@ LinkRanges textParseLinks(const QString &text, int32 flags, bool rich) { // some
|
||||
continue;
|
||||
}
|
||||
}
|
||||
link.len = p - link.from;
|
||||
lnkLength = (p - start) - lnkOffset;
|
||||
}
|
||||
}
|
||||
lnkRanges.push_back(link);
|
||||
result.push_back(LinkInText(lnkType, lnkOffset, lnkLength));
|
||||
|
||||
offset = matchOffset = (link.from - start) + link.len;
|
||||
offset = matchOffset = lnkOffset + lnkLength;
|
||||
}
|
||||
|
||||
return lnkRanges;
|
||||
return result;
|
||||
}
|
||||
|
||||
void emojiDraw(QPainter &p, EmojiPtr e, int x, int y) {
|
||||
|
@ -39,14 +39,57 @@ enum {
|
||||
TextInstagramHashtags = 0x200,
|
||||
};
|
||||
|
||||
struct LinkRange {
|
||||
LinkRange() : from(0), len(0) {
|
||||
}
|
||||
const QChar *from;
|
||||
int32 len;
|
||||
enum LinkInTextType {
|
||||
LinkInTextUrl,
|
||||
LinkInTextCustomUrl,
|
||||
LinkInTextEmail,
|
||||
LinkInTextHashtag,
|
||||
LinkInTextMention,
|
||||
LinkInTextBotCommand,
|
||||
};
|
||||
typedef QVector<LinkRange> LinkRanges;
|
||||
LinkRanges textParseLinks(const QString &text, int32 flags, bool rich = false);
|
||||
struct LinkInText {
|
||||
LinkInText(LinkInTextType type, int32 offset, int32 length, const QString &text = QString()) : type(type), offset(offset), length(length), text(text) {
|
||||
}
|
||||
LinkInTextType type;
|
||||
int32 offset, length;
|
||||
QString text;
|
||||
};
|
||||
typedef QList<LinkInText> LinksInText;
|
||||
inline LinksInText linksFromMTP(const QVector<MTPMessageEntity> &entities) {
|
||||
LinksInText result;
|
||||
if (!entities.isEmpty()) {
|
||||
result.reserve(entities.size());
|
||||
for (int32 i = 0, l = entities.size(); i != l; ++i) {
|
||||
const MTPMessageEntity &e(entities.at(i));
|
||||
switch (e.type()) {
|
||||
case mtpc_messageEntityUrl: { const MTPDmessageEntityUrl &d(e.c_messageEntityUrl()); result.push_back(LinkInText(LinkInTextUrl, d.voffset.v, d.vlength.v)); } break;
|
||||
case mtpc_messageEntityTextUrl: { const MTPDmessageEntityTextUrl &d(e.c_messageEntityTextUrl()); result.push_back(LinkInText(LinkInTextCustomUrl, d.voffset.v, d.vlength.v, textClean(qs(d.vurl)))); } break;
|
||||
case mtpc_messageEntityEmail: { const MTPDmessageEntityEmail &d(e.c_messageEntityEmail()); result.push_back(LinkInText(LinkInTextEmail, d.voffset.v, d.vlength.v)); } break;
|
||||
case mtpc_messageEntityHashtag: { const MTPDmessageEntityHashtag &d(e.c_messageEntityHashtag()); result.push_back(LinkInText(LinkInTextHashtag, d.voffset.v, d.vlength.v)); } break;
|
||||
case mtpc_messageEntityMention: { const MTPDmessageEntityMention &d(e.c_messageEntityMention()); result.push_back(LinkInText(LinkInTextMention, d.voffset.v, d.vlength.v)); } break;
|
||||
case mtpc_messageEntityBotCommand: { const MTPDmessageEntityBotCommand &d(e.c_messageEntityBotCommand()); result.push_back(LinkInText(LinkInTextBotCommand, d.voffset.v, d.vlength.v)); } break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
inline MTPVector<MTPMessageEntity> linksToMTP(const LinksInText &links) {
|
||||
MTPVector<MTPMessageEntity> result(MTP_vector<MTPMessageEntity>(0));
|
||||
QVector<MTPMessageEntity> &v(result._vector().v);
|
||||
for (int32 i = 0, s = links.size(); i != s; ++i) {
|
||||
const LinkInText &l(links.at(i));
|
||||
switch (l.type) {
|
||||
case LinkInTextUrl: v.push_back(MTP_messageEntityUrl(MTP_int(l.offset), MTP_int(l.length))); break;
|
||||
case LinkInTextCustomUrl: v.push_back(MTP_messageEntityTextUrl(MTP_int(l.offset), MTP_int(l.length), MTP_string(l.text))); break;
|
||||
case LinkInTextEmail: v.push_back(MTP_messageEntityEmail(MTP_int(l.offset), MTP_int(l.length))); break;
|
||||
case LinkInTextHashtag: v.push_back(MTP_messageEntityHashtag(MTP_int(l.offset), MTP_int(l.length))); break;
|
||||
case LinkInTextMention: v.push_back(MTP_messageEntityMention(MTP_int(l.offset), MTP_int(l.length))); break;
|
||||
case LinkInTextBotCommand: v.push_back(MTP_messageEntityBotCommand(MTP_int(l.offset), MTP_int(l.length))); break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
LinksInText textParseLinks(const QString &text, int32 flags, bool rich = false);
|
||||
|
||||
#include "gui/emoji_config.h"
|
||||
|
||||
@ -326,11 +369,7 @@ public:
|
||||
return _email;
|
||||
}
|
||||
|
||||
void onClick(Qt::MouseButton button) const {
|
||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
||||
QDesktopServices::openUrl(qsl("mailto:") + _email);
|
||||
}
|
||||
}
|
||||
void onClick(Qt::MouseButton button) const;
|
||||
|
||||
const QString &readable() const {
|
||||
return _email;
|
||||
@ -475,6 +514,7 @@ public:
|
||||
int32 countHeight(int32 width) const;
|
||||
void setText(style::font font, const QString &text, const TextParseOptions &options = _defaultOptions);
|
||||
void setRichText(style::font font, const QString &text, TextParseOptions options = _defaultOptions, const TextCustomTagsMap &custom = TextCustomTagsMap());
|
||||
void setMarkedText(style::font font, const QString &text, const LinksInText &links, const TextParseOptions &options = _defaultOptions);
|
||||
|
||||
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
|
||||
bool hasLinks() const;
|
||||
@ -482,6 +522,9 @@ public:
|
||||
bool hasSkipBlock() const {
|
||||
return _blocks.isEmpty() ? false : _blocks.back()->type() == TextBlockSkip;
|
||||
}
|
||||
void setSkipBlock(int32 width, int32 height);
|
||||
void removeSkipBlock();
|
||||
LinksInText calcLinksInText() const;
|
||||
|
||||
int32 maxWidth() const {
|
||||
return _maxWidth.ceil().toInt();
|
||||
@ -534,6 +577,8 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
void recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir = Qt::LayoutDirectionAuto);
|
||||
|
||||
QFixed _minResizeWidth, _maxWidth;
|
||||
int32 _minHeight;
|
||||
|
||||
@ -591,7 +636,7 @@ inline bool chIsSpace(QChar ch, bool rich = false) {
|
||||
return ch.isSpace() || (ch < 32 && !(rich && ch == TextCommand)) || (ch == QChar::ParagraphSeparator) || (ch == QChar::LineSeparator) || (ch == QChar::ObjectReplacementCharacter) || (ch == QChar::SoftHyphen) || (ch == QChar::CarriageReturn) || (ch == QChar::Tabulation);
|
||||
}
|
||||
inline bool chIsBad(QChar ch) {
|
||||
return (ch == 0) || (ch >= 8232 && ch < 8239) || (ch >= 65024 && ch < 65040 && ch != 65039) || (ch >= 127 && ch < 160 && ch != 156);
|
||||
return (ch == 0) || (ch >= 8232 && ch < 8237) || (ch >= 65024 && ch < 65040 && ch != 65039) || (ch >= 127 && ch < 160 && ch != 156);
|
||||
}
|
||||
inline bool chIsTrimmed(QChar ch, bool rich = false) {
|
||||
return (!rich || ch != TextCommand) && (chIsSpace(ch) || chIsBad(ch));
|
||||
|
@ -110,15 +110,17 @@ namespace {
|
||||
return item ? item->toHistoryForwarded() : 0;
|
||||
}
|
||||
inline const TextParseOptions &itemTextParseOptions(HistoryItem *item) {
|
||||
History *h = item->history();
|
||||
UserData *f = item->from();
|
||||
if ((!h->peer->chat && h->peer->asUser()->botInfo) || (!f->chat && f->asUser()->botInfo) || (h->peer->chat && h->peer->asChat()->botStatus >= 0)) {
|
||||
return _historyBotOptions;
|
||||
}
|
||||
return _historyTextOptions;
|
||||
return itemTextParseOptions(item->history(), item->from());
|
||||
}
|
||||
}
|
||||
|
||||
const TextParseOptions &itemTextParseOptions(History *h, UserData *f) {
|
||||
if ((!h->peer->chat && h->peer->asUser()->botInfo) || (!f->chat && f->asUser()->botInfo) || (h->peer->chat && h->peer->asChat()->botStatus >= 0)) {
|
||||
return _historyBotOptions;
|
||||
}
|
||||
return _historyTextOptions;
|
||||
}
|
||||
|
||||
void historyInit() {
|
||||
_initTextOptions();
|
||||
}
|
||||
@ -346,7 +348,7 @@ bool History::updateTyping(uint64 ms, uint32 dots, bool force) {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
for (SendActionUsers::iterator i = sendActions.begin(), e = sendActions.end(); i != e;) {
|
||||
for (SendActionUsers::iterator i = sendActions.begin(); i != sendActions.cend();) {
|
||||
if (ms >= i.value().until) {
|
||||
i = sendActions.erase(i);
|
||||
changed = true;
|
||||
@ -643,7 +645,9 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
|
||||
|
||||
const MTPMessageMedia *media = 0;
|
||||
switch (msg.type()) {
|
||||
case mtpc_message: media = &msg.c_message().vmedia; break;
|
||||
case mtpc_message:
|
||||
media = msg.c_message().has_media() ? (&msg.c_message().vmedia) : 0;
|
||||
break;
|
||||
}
|
||||
if (media) {
|
||||
existing->updateMedia(*media);
|
||||
@ -659,7 +663,7 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPmessage &msg, boo
|
||||
case mtpc_message: {
|
||||
const MTPDmessage m(msg.c_message());
|
||||
int badMedia = 0; // 1 - unsupported, 2 - empty
|
||||
switch (m.vmedia.type()) {
|
||||
if (m.has_media()) switch (m.vmedia.type()) {
|
||||
case mtpc_messageMediaEmpty:
|
||||
case mtpc_messageMediaContact: break;
|
||||
case mtpc_messageMediaGeo:
|
||||
@ -886,6 +890,24 @@ void History::createInitialDateBlock(const QDateTime &date) {
|
||||
push_front(dateBlock); // date block
|
||||
}
|
||||
|
||||
void History::addToOverview(HistoryItem *item, MediaOverviewType type) {
|
||||
if (_overviewIds[type].constFind(item->id) == _overviewIds[type].cend()) {
|
||||
_overview[type].push_back(item->id);
|
||||
_overviewIds[type].insert(item->id, NullType());
|
||||
if (_overviewCount[type] > 0) ++_overviewCount[type];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, type);
|
||||
}
|
||||
}
|
||||
|
||||
bool History::addToOverviewFront(HistoryItem *item, MediaOverviewType type) {
|
||||
if (_overviewIds[type].constFind(item->id) == _overviewIds[type].cend()) {
|
||||
_overview[type].push_front(item->id);
|
||||
_overviewIds[type].insert(item->id, NullType());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg) {
|
||||
if (!adding) {
|
||||
if (newBlock) delete to;
|
||||
@ -926,23 +948,15 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||
HistoryMediaType mt = media->type();
|
||||
MediaOverviewType t = mediaToOverviewType(mt);
|
||||
if (t != OverviewCount) {
|
||||
if (_overviewIds[t].constFind(adding->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_back(adding->id);
|
||||
_overviewIds[t].insert(adding->id, NullType());
|
||||
if (_overviewCount[t] > 0) ++_overviewCount[t];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, t);
|
||||
}
|
||||
addToOverview(adding, t);
|
||||
if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) {
|
||||
t = OverviewAudioDocuments;
|
||||
if (_overviewIds[t].constFind(adding->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_back(adding->id);
|
||||
_overviewIds[t].insert(adding->id, NullType());
|
||||
if (_overviewCount[t] > 0) ++_overviewCount[t];
|
||||
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, t);
|
||||
}
|
||||
addToOverview(adding, OverviewAudioDocuments);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (adding->hasTextLinks()) {
|
||||
addToOverview(adding, OverviewLinks);
|
||||
}
|
||||
if (adding->from()->id) {
|
||||
if (peer->chat) {
|
||||
QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
|
||||
@ -1026,7 +1040,7 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
|
||||
int32 addToH = 0, skip = 0;
|
||||
if (!isEmpty()) {
|
||||
addToH = -front()->height;
|
||||
if (width) addToH = -front()->height;
|
||||
pop_front(); // remove date block
|
||||
}
|
||||
HistoryItem *till = isEmpty() ? 0 : front()->front(), *prev = 0;
|
||||
@ -1040,12 +1054,16 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
if (prev && prev->date.date() != adding->date.date()) {
|
||||
HistoryItem *dayItem = createDayServiceMsg(this, block, adding->date);
|
||||
block->push_back(dayItem);
|
||||
dayItem->y = block->height;
|
||||
block->height += dayItem->resize(width);
|
||||
if (width) {
|
||||
dayItem->y = block->height;
|
||||
block->height += dayItem->resize(width);
|
||||
}
|
||||
}
|
||||
block->push_back(adding);
|
||||
adding->y = block->height;
|
||||
block->height += adding->resize(width);
|
||||
if (width) {
|
||||
adding->y = block->height;
|
||||
block->height += adding->resize(width);
|
||||
}
|
||||
setMsgCount(msgCount + 1);
|
||||
prev = adding;
|
||||
}
|
||||
@ -1054,8 +1072,10 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
if (till && prev && prev->date.date() != till->date.date()) {
|
||||
HistoryItem *dayItem = createDayServiceMsg(this, block, till->date);
|
||||
block->push_back(dayItem);
|
||||
dayItem->y = block->height;
|
||||
block->height += dayItem->resize(width);
|
||||
if (width) {
|
||||
dayItem->y = block->height;
|
||||
block->height += dayItem->resize(width);
|
||||
}
|
||||
}
|
||||
if (block->size()) {
|
||||
if (loadedAtBottom() && wasMsgCount < unreadCount && msgCount >= unreadCount) {
|
||||
@ -1070,8 +1090,10 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
}
|
||||
}
|
||||
push_front(block);
|
||||
addToH += block->height;
|
||||
++skip;
|
||||
if (width) {
|
||||
addToH += block->height;
|
||||
++skip;
|
||||
}
|
||||
|
||||
if (loadedAtBottom()) { // add photos to overview and authors to lastAuthors
|
||||
int32 mask = 0;
|
||||
@ -1083,21 +1105,15 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
HistoryMediaType mt = media->type();
|
||||
MediaOverviewType t = mediaToOverviewType(mt);
|
||||
if (t != OverviewCount) {
|
||||
if (_overviewIds[t].constFind(item->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_front(item->id);
|
||||
_overviewIds[t].insert(item->id, NullType());
|
||||
mask |= (1 << t);
|
||||
}
|
||||
if (addToOverviewFront(item, t)) mask |= (1 << t);
|
||||
if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) {
|
||||
t = OverviewAudioDocuments;
|
||||
if (_overviewIds[t].constFind(item->id) == _overviewIds[t].cend()) {
|
||||
_overview[t].push_front(item->id);
|
||||
_overviewIds[t].insert(item->id, NullType());
|
||||
mask |= (1 << t);
|
||||
}
|
||||
if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item->hasTextLinks()) {
|
||||
if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks);
|
||||
}
|
||||
if (item->from()->id) {
|
||||
if (lastAuthors) { // chats
|
||||
if (!lastAuthors->contains(item->from())) {
|
||||
@ -1150,16 +1166,18 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||
HistoryBlock *dateBlock = new HistoryBlock(this);
|
||||
HistoryItem *dayItem = createDayServiceMsg(this, dateBlock, front()->front()->date);
|
||||
dateBlock->push_back(dayItem);
|
||||
int32 dh = dayItem->resize(width);
|
||||
dateBlock->height = dh;
|
||||
if (skip) {
|
||||
front()->y += dh;
|
||||
if (width) {
|
||||
int32 dh = dayItem->resize(width);
|
||||
dateBlock->height = dh;
|
||||
if (skip) {
|
||||
front()->y += dh;
|
||||
}
|
||||
addToH += dh;
|
||||
++skip;
|
||||
}
|
||||
push_front(dateBlock); // date block
|
||||
addToH += dh;
|
||||
++skip;
|
||||
}
|
||||
if (addToH) {
|
||||
if (width && addToH) {
|
||||
for (iterator i = begin(), e = end(); i != e; ++i) {
|
||||
if (skip) {
|
||||
--skip;
|
||||
@ -1249,6 +1267,14 @@ void History::addToBack(const QVector<MTPMessage> &slice) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item->hasTextLinks()) {
|
||||
MediaOverviewType t = OverviewLinks;
|
||||
if (_overviewCount[t] != 0) {
|
||||
_overview[t].push_back(item->id);
|
||||
_overviewIds[t].insert(item->id, NullType());
|
||||
mask |= (1 << t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int32 t = 0; t < OverviewCount; ++t) {
|
||||
@ -1311,7 +1337,7 @@ void History::setUnreadCount(int32 newUnreadCount, bool psUpdate) {
|
||||
App::histories().unreadFull += newUnreadCount - unreadCount;
|
||||
if (mute) App::histories().unreadMuted += newUnreadCount - unreadCount;
|
||||
unreadCount = newUnreadCount;
|
||||
if (psUpdate) App::wnd()->updateCounter();
|
||||
if (psUpdate && (!mute || cIncludeMuted())) App::wnd()->updateCounter();
|
||||
if (unreadBar) unreadBar->setCount(unreadCount);
|
||||
}
|
||||
}
|
||||
@ -1760,6 +1786,9 @@ void HistoryItem::destroy() {
|
||||
history()->eraseFromOverview(OverviewAudioDocuments, id);
|
||||
}
|
||||
}
|
||||
if (hasTextLinks()) {
|
||||
history()->eraseFromOverview(OverviewLinks, id);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
@ -1976,19 +2005,37 @@ void HistoryPhoto::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
|
||||
return fwd->getForwardedState(lnk, state, x - st::mediaPadding.left(), width - st::mediaPadding.left() - st::mediaPadding.right());
|
||||
}
|
||||
}
|
||||
height -= st::mediaPadding.bottom();
|
||||
height -= skipy + st::mediaPadding.bottom();
|
||||
width -= st::mediaPadding.left() + st::mediaPadding.right();
|
||||
if (!_caption.isEmpty()) {
|
||||
int32 dateX = skipx + width + st::msgDateDelta.x() - parent->timeWidth(true) + st::msgDateSpace;
|
||||
int32 dateY = _height - st::msgPadding.bottom() + st::msgDateDelta.y() - st::msgDateFont->height;
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
|
||||
height -= _caption.countHeight(width) + st::webPagePhotoSkip;
|
||||
if (x >= skipx && y >= height + st::webPagePhotoSkip && x < skipx + width && y < _height) {
|
||||
if (x >= skipx && y >= skipy + height + st::webPagePhotoSkip && x < skipx + width && y < _height) {
|
||||
bool inText = false;
|
||||
_caption.getState(lnk, inText, x - skipx, y - height - st::webPagePhotoSkip, width);
|
||||
state = inText ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
||||
_caption.getState(lnk, inText, x - skipx, y - skipy - height - st::webPagePhotoSkip, width);
|
||||
state = inDate ? HistoryInDateCursorState : (inText ? HistoryInTextCursorState : HistoryDefaultCursorState);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (x >= skipx && y >= skipy && x < skipx + width && y < height) {
|
||||
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
|
||||
lnk = openl;
|
||||
if (_caption.isEmpty()) {
|
||||
int32 dateX = skipx + width - parent->timeWidth(false) - st::msgDateImgDelta - st::msgDateImgPadding.x();
|
||||
int32 dateY = skipy + height - st::msgDateFont->height - st::msgDateImgDelta - st::msgDateImgPadding.y();
|
||||
if (parent->out()) {
|
||||
dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
|
||||
}
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2230,15 +2277,11 @@ HistoryVideo::HistoryVideo(const MTPDvideo &video, const QString &caption, Histo
|
||||
|
||||
int32 tw = data->thumb->width(), th = data->thumb->height();
|
||||
if (data->thumb->isNull() || !tw || !th) {
|
||||
_thumbw = _thumbx = _thumby = 0;
|
||||
_thumbw = 0;
|
||||
} else if (tw > th) {
|
||||
_thumbw = (tw * st::mediaThumbSize) / th;
|
||||
_thumbx = (_thumbw - st::mediaThumbSize) / 2;
|
||||
_thumby = 0;
|
||||
} else {
|
||||
_thumbw = st::mediaThumbSize;
|
||||
_thumbx = 0;
|
||||
_thumby = ((th * _thumbw) / tw - st::mediaThumbSize) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2387,6 +2430,13 @@ void HistoryVideo::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
|
||||
}
|
||||
}
|
||||
|
||||
int32 dateX = width - st::msgPadding.right() + st::msgDateDelta.x() - parent->timeWidth(true) + st::msgDateSpace;
|
||||
int32 dateY = height - st::msgPadding.bottom() + st::msgDateDelta.y() - st::msgDateFont->height;
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
|
||||
int32 tw = width - st::mediaPadding.left() - st::mediaPadding.right();
|
||||
if (x >= st::mediaPadding.left() && y >= skipy + st::mediaPadding.top() && x < st::mediaPadding.left() + tw && y < skipy + st::mediaPadding.top() + st::mediaThumbSize && !data->loader && data->access) {
|
||||
lnk = _openl;
|
||||
@ -2395,7 +2445,7 @@ void HistoryVideo::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
|
||||
if (!_caption.isEmpty() && x >= st::mediaPadding.left() && x < st::mediaPadding.left() + tw && y >= skipy + st::mediaPadding.top() + st::mediaThumbSize + st::webPagePhotoSkip) {
|
||||
bool inText = false;
|
||||
_caption.getState(lnk, inText, x - st::mediaPadding.left(), y - skipy - st::mediaPadding.top() - st::mediaThumbSize - st::webPagePhotoSkip, tw);
|
||||
state = inText ? HistoryInTextCursorState : HistoryDefaultCursorState;
|
||||
state = inDate ? HistoryInDateCursorState : (inText ? HistoryInTextCursorState : HistoryDefaultCursorState);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2883,6 +2933,14 @@ void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
|
||||
|
||||
if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
|
||||
lnk = _openl;
|
||||
|
||||
int32 dateX = width - st::msgPadding.right() + st::msgDateDelta.x() - parent->timeWidth(true) + st::msgDateSpace;
|
||||
int32 dateY = _height - st::msgPadding.bottom() + st::msgDateDelta.y() - st::msgDateFont->height;
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2925,15 +2983,11 @@ HistoryDocument::HistoryDocument(DocumentData *document) : HistoryMedia()
|
||||
|
||||
int32 tw = data->thumb->width(), th = data->thumb->height();
|
||||
if (data->thumb->isNull() || !tw || !th) {
|
||||
_thumbw = _thumbx = _thumby = 0;
|
||||
_thumbw = 0;
|
||||
} else if (tw > th) {
|
||||
_thumbw = (tw * st::mediaThumbSize) / th;
|
||||
_thumbx = (_thumbw - st::mediaThumbSize) / 2;
|
||||
_thumby = 0;
|
||||
} else {
|
||||
_thumbw = st::mediaThumbSize;
|
||||
_thumbx = 0;
|
||||
_thumby = ((th * _thumbw) / tw - st::mediaThumbSize) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3399,6 +3453,14 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
|
||||
|
||||
if (x >= 0 && y >= skipy && x < width && y < _height && !data->loader && data->access) {
|
||||
lnk = _openl;
|
||||
|
||||
int32 dateX = width - st::msgPadding.right() + st::msgDateDelta.x() - parent->timeWidth(true) + st::msgDateSpace;
|
||||
int32 dateY = _height - st::msgPadding.bottom() + st::msgDateDelta.y() - st::msgDateFont->height;
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3408,17 +3470,7 @@ HistoryMedia *HistoryDocument::clone() const {
|
||||
}
|
||||
|
||||
ImagePtr HistoryDocument::replyPreview() {
|
||||
if (data->replyPreview->isNull() && !data->thumb->isNull()) {
|
||||
if (data->thumb->loaded()) {
|
||||
int w = data->thumb->width(), h = data->thumb->height();
|
||||
if (w <= 0) w = 1;
|
||||
if (h <= 0) h = 1;
|
||||
data->replyPreview = ImagePtr(w > h ? data->thumb->pix(w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : data->thumb->pix(st::msgReplyBarSize.height()), "PNG");
|
||||
} else {
|
||||
data->thumb->load();
|
||||
}
|
||||
}
|
||||
return data->replyPreview;
|
||||
return data->makeReplyPreview();
|
||||
}
|
||||
|
||||
HistorySticker::HistorySticker(DocumentData *document) : HistoryMedia()
|
||||
@ -3581,6 +3633,10 @@ void HistorySticker::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||
const HistoryReply *reply = toHistoryReply(parent);
|
||||
if (reply) {
|
||||
usew -= reply->replyToWidth();
|
||||
if (parent->out()) {
|
||||
usex = width - usew;
|
||||
}
|
||||
|
||||
int32 rw = width - usew, rh = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||
int32 rx = parent->out() ? 0 : usew, ry = _height - rh;
|
||||
if (x >= rx && y >= ry && x < rx + rw && y < ry + rh) {
|
||||
@ -3588,6 +3644,15 @@ void HistorySticker::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||
return;
|
||||
}
|
||||
}
|
||||
int32 dateX = usex + usew - parent->timeWidth(false) - st::msgDateImgDelta - st::msgDateImgPadding.x();
|
||||
int32 dateY = _height - st::msgDateFont->height - st::msgDateImgDelta - st::msgDateImgPadding.y();
|
||||
if (parent->out()) {
|
||||
dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
|
||||
}
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
}
|
||||
|
||||
HistoryMedia *HistorySticker::clone() const {
|
||||
@ -3599,18 +3664,14 @@ HistoryContact::HistoryContact(int32 userId, const QString &first, const QString
|
||||
, phone(App::formatPhone(phone))
|
||||
, contact(App::userLoaded(userId))
|
||||
{
|
||||
App::regSharedContactPhone(userId, phone);
|
||||
|
||||
_maxw = st::mediaMaxWidth;
|
||||
name.setText(st::mediaFont, (first + ' ' + last).trimmed(), _textNameOptions);
|
||||
|
||||
phonew = st::mediaFont->m.width(phone);
|
||||
|
||||
if (contact) {
|
||||
if (contact->phone.isEmpty()) {
|
||||
contact->setPhone(phone);
|
||||
}
|
||||
if (contact->contact < 0) {
|
||||
contact->contact = 0;
|
||||
}
|
||||
contact->photo->load();
|
||||
}
|
||||
}
|
||||
@ -3811,13 +3872,16 @@ void HistoryContact::updateFrom(const MTPMessageMedia &media) {
|
||||
|
||||
HistoryWebPage::HistoryWebPage(WebPageData *data) : HistoryMedia()
|
||||
, data(data)
|
||||
, _openl(data->url.isEmpty() ? 0 : new TextLink(data->url))
|
||||
, _photol((data->photo && data->type != WebPageVideo) ? new PhotoLink(data->photo) : 0)
|
||||
, _openl(0)
|
||||
, _attachl(0)
|
||||
, _asArticle(false)
|
||||
, _title(st::msgMinWidth - st::webPageLeft)
|
||||
, _description(st::msgMinWidth - st::webPageLeft)
|
||||
, _siteNameWidth(0)
|
||||
, _durationWidth(0)
|
||||
, _docNameWidth(0)
|
||||
, _docThumbWidth(0)
|
||||
, _docDownloadDone(0)
|
||||
, _pixw(0), _pixh(0)
|
||||
{
|
||||
}
|
||||
@ -3831,7 +3895,9 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||
return;
|
||||
}
|
||||
if (!_openl && !data->url.isEmpty()) _openl = TextLinkPtr(new TextLink(data->url));
|
||||
if (!_photol && data->photo && data->type != WebPageVideo) _photol = TextLinkPtr(new PhotoLink(data->photo));
|
||||
if (!_attachl && data->photo && data->type != WebPageVideo) _attachl = TextLinkPtr(new PhotoLink(data->photo));
|
||||
if (!_attachl && data->doc) _attachl = TextLinkPtr(new DocumentOpenLink(data->doc));
|
||||
|
||||
if (data->photo && data->type != WebPagePhoto && data->type != WebPageVideo) {
|
||||
if (data->type == WebPageProfile) {
|
||||
_asArticle = true;
|
||||
@ -3843,6 +3909,7 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||
} else {
|
||||
_asArticle = false;
|
||||
}
|
||||
|
||||
if (_asArticle) {
|
||||
w = st::webPagePhotoSize;
|
||||
_maxw = st::webPageLeft + st::webPagePhotoSize;
|
||||
@ -3869,6 +3936,31 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||
_maxw = st::webPageLeft + qMax(thumbh, qMax(w, int32(st::minPhotoSize))) + parent->timeWidth(true);
|
||||
_minh = qMax(thumbh, int32(st::minPhotoSize));
|
||||
_minh += st::webPagePhotoSkip;
|
||||
} else if (data->doc) {
|
||||
if (!data->doc->thumb->isNull()) {
|
||||
data->doc->thumb->load();
|
||||
|
||||
int32 tw = data->doc->thumb->width(), th = data->doc->thumb->height();
|
||||
if (data->doc->thumb->isNull() || !tw || !th) {
|
||||
_docThumbWidth = 0;
|
||||
} else if (tw > th) {
|
||||
_docThumbWidth = (tw * st::mediaThumbSize) / th;
|
||||
} else {
|
||||
_docThumbWidth = st::mediaThumbSize;
|
||||
}
|
||||
}
|
||||
_docName = documentName(data->doc);
|
||||
_docSize = data->doc->song() ? formatDurationAndSizeText(data->doc->song()->duration, data->doc->size) : formatSizeText(data->doc->size);
|
||||
_docNameWidth = st::mediaFont->m.width(_docName.isEmpty() ? qsl("Document") : _docName);
|
||||
|
||||
if (parent == animated.msg) {
|
||||
_maxw = st::webPageLeft + (animated.w / cIntRetinaFactor()) + parent->timeWidth(true);
|
||||
_minh = animated.h / cIntRetinaFactor();
|
||||
_minh += st::webPagePhotoSkip;
|
||||
} else {
|
||||
_maxw = qMax(st::webPageLeft + st::mediaThumbSize + st::mediaPadding.right() + _docNameWidth + st::mediaPadding.right(), st::mediaMaxWidth);
|
||||
_minh = st::mediaThumbSize;
|
||||
}
|
||||
} else {
|
||||
_maxw = st::webPageLeft;
|
||||
_minh = 0;
|
||||
@ -3912,7 +4004,7 @@ void HistoryWebPage::initDimensions(const HistoryItem *parent) {
|
||||
_minh += qMin(_description.minHeight(), 3 * st::webPageTitleFont->height);
|
||||
}
|
||||
}
|
||||
if (!_asArticle && data->photo && (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty())) {
|
||||
if (!_asArticle && (data->photo || data->doc) && (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty())) {
|
||||
_minh += st::webPagePhotoSkip;
|
||||
}
|
||||
if (data->type == WebPageVideo && data->duration) {
|
||||
@ -3926,15 +4018,29 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
|
||||
if (width < 0) width = w;
|
||||
if (width < 1 || data->pendingTill) return;
|
||||
|
||||
int32 bottomSkip = 0;
|
||||
//if (!data->pendingTill) {
|
||||
if (data->photo) {
|
||||
bottomSkip += st::webPagePhotoSkip;
|
||||
if (_asArticle || (st::webPageLeft + qMax(_pixw, int16(st::minPhotoSize)) + parent->timeWidth(true) > width)) {
|
||||
bottomSkip += (st::msgDateFont->height - st::msgDateDelta.y());
|
||||
}
|
||||
int16 animw = 0, animh = 0;
|
||||
if (data->doc && animated.msg == parent) {
|
||||
animw = animated.w / cIntRetinaFactor();
|
||||
animh = animated.h / cIntRetinaFactor();
|
||||
if (width - st::webPageLeft < animw) {
|
||||
animw = width - st::webPageLeft;
|
||||
animh = (animw * animated.h / animated.w);
|
||||
if (animh < 1) animh = 1;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
int32 bottomSkip = 0;
|
||||
if (data->photo) {
|
||||
bottomSkip += st::webPagePhotoSkip;
|
||||
if (_asArticle || (st::webPageLeft + qMax(_pixw, int16(st::minPhotoSize)) + parent->timeWidth(true) > width)) {
|
||||
bottomSkip += (st::msgDateFont->height - st::msgDateDelta.y());
|
||||
}
|
||||
} else if (data->doc && animated.msg == parent) {
|
||||
bottomSkip += st::webPagePhotoSkip;
|
||||
if (st::webPageLeft + qMax(animw, int16(st::minPhotoSize)) + parent->timeWidth(true) > width) {
|
||||
bottomSkip += (st::msgDateFont->height - st::msgDateDelta.y());
|
||||
}
|
||||
}
|
||||
|
||||
style::color bar = (selected ? (parent->out() ? st::msgOutReplyBarSelColor : st::msgInReplyBarSelColor) : (parent->out() ? st::msgOutReplyBarColor : st::msgInReplyBarColor));
|
||||
style::color semibold = (selected ? (parent->out() ? st::msgOutServiceSelColor : st::msgInServiceSelColor) : (parent->out() ? st::msgOutServiceColor : st::msgInServiceColor));
|
||||
@ -4076,6 +4182,100 @@ void HistoryWebPage::draw(QPainter &p, const HistoryItem *parent, bool selected,
|
||||
}
|
||||
|
||||
p.translate(0, pixheight);
|
||||
} else if (!_asArticle && data->doc) {
|
||||
if (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty()) {
|
||||
p.translate(0, st::webPagePhotoSkip);
|
||||
}
|
||||
|
||||
if (parent == animated.msg) {
|
||||
p.drawPixmap(0, 0, animated.current(animw * cIntRetinaFactor(), animh * cIntRetinaFactor(), true));
|
||||
if (selected) {
|
||||
App::roundRect(p, 0, 0, animw, animh, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
|
||||
}
|
||||
} else {
|
||||
QString statusText;
|
||||
if (data->doc->song()) {
|
||||
SongMsgId playing;
|
||||
AudioPlayerState playingState = AudioPlayerStopped;
|
||||
int64 playingPosition = 0, playingDuration = 0;
|
||||
int32 playingFrequency = 0;
|
||||
if (audioPlayer()) {
|
||||
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
|
||||
}
|
||||
|
||||
bool already = !data->doc->already().isEmpty(), hasdata = !data->doc->data.isEmpty();
|
||||
QRect img;
|
||||
if (data->doc->status == FileFailed) {
|
||||
statusText = lang(lng_attach_failed);
|
||||
img = parent->out() ? st::mediaMusicOutImg : st::mediaMusicInImg;
|
||||
} else if (already || hasdata) {
|
||||
bool showPause = false;
|
||||
if (playing.msgId == parent->id && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
|
||||
statusText = formatDurationText(playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency)) + qsl(" / ") + formatDurationText(playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
|
||||
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
|
||||
} else {
|
||||
statusText = formatDurationText(data->doc->song()->duration);
|
||||
}
|
||||
if (!showPause && playing.msgId == parent->id && App::main() && App::main()->player()->seekingSong(playing)) showPause = true;
|
||||
img = parent->out() ? (showPause ? st::mediaPauseOutImg : st::mediaPlayOutImg) : (showPause ? st::mediaPauseInImg : st::mediaPlayInImg);
|
||||
} else {
|
||||
if (data->doc->loader) {
|
||||
int32 offset = data->doc->loader->currentOffset();
|
||||
if (_docDownloadTextCache.isEmpty() || _docDownloadDone != offset) {
|
||||
_docDownloadDone = offset;
|
||||
_docDownloadTextCache = formatDownloadText(_docDownloadDone, data->doc->size);
|
||||
}
|
||||
statusText = _docDownloadTextCache;
|
||||
} else {
|
||||
statusText = _docSize;
|
||||
}
|
||||
img = parent->out() ? st::mediaMusicOutImg : st::mediaMusicInImg;
|
||||
}
|
||||
|
||||
p.drawPixmap(QPoint(0, 0), App::sprite(), img);
|
||||
} else {
|
||||
if (data->doc->status == FileFailed) {
|
||||
statusText = lang(lng_attach_failed);
|
||||
} else if (data->doc->loader) {
|
||||
int32 offset = data->doc->loader->currentOffset();
|
||||
if (_docDownloadTextCache.isEmpty() || _docDownloadDone != offset) {
|
||||
_docDownloadDone = offset;
|
||||
_docDownloadTextCache = formatDownloadText(_docDownloadDone, data->doc->size);
|
||||
}
|
||||
statusText = _docDownloadTextCache;
|
||||
} else {
|
||||
statusText = _docSize;
|
||||
}
|
||||
|
||||
if (_docThumbWidth) {
|
||||
data->doc->thumb->checkload();
|
||||
p.drawPixmap(QPoint(0, 0), data->doc->thumb->pixSingle(_docThumbWidth, 0, st::mediaThumbSize, st::mediaThumbSize));
|
||||
} else {
|
||||
p.drawPixmap(QPoint(0, 0), App::sprite(), (parent->out() ? st::mediaDocOutImg : st::mediaDocInImg));
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
App::roundRect(p, 0, 0, st::mediaThumbSize, st::mediaThumbSize, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
|
||||
}
|
||||
|
||||
int32 tleft = st::mediaPadding.left() + st::mediaThumbSize + st::mediaPadding.right();
|
||||
int32 twidth = width - tleft - st::mediaPadding.right();
|
||||
int32 fullTimeWidth = parent->timeWidth(true) + st::msgPadding.right();
|
||||
int32 secondwidth = width - tleft - fullTimeWidth;
|
||||
|
||||
p.setFont(st::mediaFont->f);
|
||||
p.setPen(st::black->c);
|
||||
if (twidth < _docNameWidth) {
|
||||
p.drawText(tleft, st::mediaNameTop + st::mediaFont->ascent, st::mediaFont->m.elidedText(_docName, Qt::ElideRight, twidth));
|
||||
} else {
|
||||
p.drawText(tleft, st::mediaNameTop + st::mediaFont->ascent, _docName);
|
||||
}
|
||||
|
||||
style::color status(selected ? (parent->out() ? st::mediaOutSelectColor : st::mediaInSelectColor) : (parent->out() ? st::mediaOutColor : st::mediaInColor));
|
||||
p.setPen(status->p);
|
||||
|
||||
p.drawText(tleft, st::mediaThumbSize - st::mediaDetailsShift - st::mediaFont->descent, statusText);
|
||||
}
|
||||
}
|
||||
|
||||
p.restore();
|
||||
@ -4108,7 +4308,7 @@ int32 HistoryWebPage::resize(int32 width, bool dontRecountText, const HistoryIte
|
||||
_height = st::webPagePhotoSize;
|
||||
_height += st::webPagePhotoSkip + (st::msgDateFont->height - st::msgDateDelta.y());
|
||||
} else if (data->photo) {
|
||||
_pixw = qMin(width, int32(_maxw - st::webPageLeft));
|
||||
_pixw = qMin(width, int32(_maxw - st::webPageLeft - parent->timeWidth(true)));
|
||||
|
||||
int32 tw = convertScale(data->photo->full->width()), th = convertScale(data->photo->full->height());
|
||||
if (tw > st::maxMediaSize) {
|
||||
@ -4136,6 +4336,24 @@ int32 HistoryWebPage::resize(int32 width, bool dontRecountText, const HistoryIte
|
||||
if (qMax(_pixw, int16(st::minPhotoSize)) + parent->timeWidth(true) > width) {
|
||||
_height += (st::msgDateFont->height - st::msgDateDelta.y());
|
||||
}
|
||||
} else if (data->doc) {
|
||||
if (parent == animated.msg) {
|
||||
int32 w = qMin(width, int32(animated.w / cIntRetinaFactor()));
|
||||
if (w > st::maxMediaSize) {
|
||||
w = st::maxMediaSize;
|
||||
}
|
||||
_height = animated.h / cIntRetinaFactor();
|
||||
if (animated.w / cIntRetinaFactor() > w) {
|
||||
_height = (w * _height / (animated.w / cIntRetinaFactor()));
|
||||
if (_height <= 0) _height = 1;
|
||||
}
|
||||
_height += st::webPagePhotoSkip;
|
||||
if (w + parent->timeWidth(true) > width) {
|
||||
_height += (st::msgDateFont->height - st::msgDateDelta.y());
|
||||
}
|
||||
} else {
|
||||
_height = st::mediaThumbSize;
|
||||
}
|
||||
} else {
|
||||
_height = 0;
|
||||
}
|
||||
@ -4150,7 +4368,7 @@ int32 HistoryWebPage::resize(int32 width, bool dontRecountText, const HistoryIte
|
||||
if (!_description.isEmpty()) {
|
||||
_height += qMin(_description.countHeight(width), st::webPageDescriptionFont->height * 3);
|
||||
}
|
||||
if (data->photo && (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty())) {
|
||||
if ((data->photo || data->doc) && (_siteNameWidth || !_title.isEmpty() || !_description.isEmpty())) {
|
||||
_height += st::webPagePhotoSkip;
|
||||
}
|
||||
}
|
||||
@ -4160,10 +4378,12 @@ int32 HistoryWebPage::resize(int32 width, bool dontRecountText, const HistoryIte
|
||||
|
||||
void HistoryWebPage::regItem(HistoryItem *item) {
|
||||
App::regWebPageItem(data, item);
|
||||
if (data->doc) App::regDocumentItem(data->doc, item);
|
||||
}
|
||||
|
||||
void HistoryWebPage::unregItem(HistoryItem *item) {
|
||||
App::unregWebPageItem(data, item);
|
||||
if (data->doc) App::unregDocumentItem(data->doc, item);
|
||||
}
|
||||
|
||||
const QString HistoryWebPage::inDialogsText() const {
|
||||
@ -4235,10 +4455,20 @@ void HistoryWebPage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||
y -= st::webPagePhotoSkip;
|
||||
}
|
||||
if (!_asArticle) {
|
||||
int32 pixwidth = qMax(_pixw, int16(st::minPhotoSize)), pixheight = qMax(_pixh, int16(st::minPhotoSize));
|
||||
if (x >= 0 && y >= 0 && x < pixwidth && y < pixheight) {
|
||||
lnk = _photol ? _photol : _openl;
|
||||
return;
|
||||
if (data->doc && parent == animated.msg) {
|
||||
int32 h = (width == w) ? _height : (width * animated.h / animated.w);
|
||||
if (h < 1) h = 1;
|
||||
if (x >= 0 && y >= 0 && x < width && y < h) {
|
||||
lnk = _attachl;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
int32 attachwidth = data->doc ? (width - st::mediaPadding.right()) : qMax(_pixw, int16(st::minPhotoSize));
|
||||
int32 attachheight = data->doc ? st::mediaThumbSize : qMax(_pixh, int16(st::minPhotoSize));
|
||||
if (x >= 0 && y >= 0 && x < attachwidth && y < attachheight) {
|
||||
lnk = _attachl ? _attachl : _openl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4248,7 +4478,7 @@ HistoryMedia *HistoryWebPage::clone() const {
|
||||
}
|
||||
|
||||
ImagePtr HistoryWebPage::replyPreview() {
|
||||
return data->photo ? data->photo->makeReplyPreview() : ImagePtr();
|
||||
return data->photo ? data->photo->makeReplyPreview() : (data->doc ? data->doc->makeReplyPreview() : ImagePtr());
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -4974,11 +5204,22 @@ void HistoryImageLink::getState(TextLinkPtr &lnk, HistoryCursorState &state, int
|
||||
return fwd->getForwardedState(lnk, state, x - st::mediaPadding.left(), width - st::mediaPadding.left() - st::mediaPadding.right());
|
||||
}
|
||||
}
|
||||
height -= st::mediaPadding.bottom();
|
||||
height -= skipy + st::mediaPadding.bottom();
|
||||
width -= st::mediaPadding.left() + st::mediaPadding.right();
|
||||
}
|
||||
if (x >= skipx && y >= skipy && x < skipx + width && y < height && data) {
|
||||
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height && data) {
|
||||
lnk = link;
|
||||
|
||||
int32 dateX = skipx + width - parent->timeWidth(false) - st::msgDateImgDelta - st::msgDateImgPadding.x();
|
||||
int32 dateY = skipy + height - st::msgDateFont->height - st::msgDateImgDelta - st::msgDateImgPadding.y();
|
||||
if (parent->out()) {
|
||||
dateX -= st::msgCheckRect.pxWidth() + st::msgDateImgCheckSpace;
|
||||
}
|
||||
bool inDate = QRect(dateX, dateY, parent->timeWidth(true) - st::msgDateSpace, st::msgDateFont->height).contains(x, y);
|
||||
if (inDate) {
|
||||
state = HistoryInDateCursorState;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -4996,11 +5237,11 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPD
|
||||
{
|
||||
QString text(textClean(qs(msg.vmessage)));
|
||||
initTime();
|
||||
initMedia(msg.vmedia, text);
|
||||
initDimensions(text);
|
||||
initMedia(msg.has_media() ? (&msg.vmedia) : 0, text);
|
||||
setText(text, msg.has_entities() ? linksFromMTP(msg.ventities.c_vector().v) : LinksInText());
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media) :
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, const MTPMessageMedia *media) :
|
||||
HistoryItem(history, block, msgId, flags, date, from)
|
||||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
@ -5010,10 +5251,10 @@ HistoryItem(history, block, msgId, flags, date, from)
|
||||
QString text(msg);
|
||||
initTime();
|
||||
initMedia(media, text);
|
||||
initDimensions(text);
|
||||
setText(text, links);
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *fromMedia) :
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, HistoryMedia *fromMedia) :
|
||||
HistoryItem(history, block, msgId, flags, date, from)
|
||||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
@ -5025,7 +5266,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
||||
_media = fromMedia->clone();
|
||||
_media->regItem(this);
|
||||
}
|
||||
initDimensions(msg);
|
||||
setText(msg, links);
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc) :
|
||||
@ -5037,7 +5278,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
||||
{
|
||||
initTime();
|
||||
initMediaFromDocument(doc);
|
||||
initDimensions(QString());
|
||||
setText(QString(), LinksInText());
|
||||
}
|
||||
|
||||
void HistoryMessage::initTime() {
|
||||
@ -5045,53 +5286,53 @@ void HistoryMessage::initTime() {
|
||||
_timeWidth = st::msgDateFont->m.width(_time);
|
||||
}
|
||||
|
||||
void HistoryMessage::initMedia(const MTPMessageMedia &media, QString ¤tText) {
|
||||
switch (media.type()) {
|
||||
void HistoryMessage::initMedia(const MTPMessageMedia *media, QString ¤tText) {
|
||||
switch (media ? media->type() : mtpc_messageMediaEmpty) {
|
||||
case mtpc_messageMediaContact: {
|
||||
const MTPDmessageMediaContact &d(media.c_messageMediaContact());
|
||||
const MTPDmessageMediaContact &d(media->c_messageMediaContact());
|
||||
_media = new HistoryContact(d.vuser_id.v, qs(d.vfirst_name), qs(d.vlast_name), qs(d.vphone_number));
|
||||
} break;
|
||||
case mtpc_messageMediaGeo: {
|
||||
const MTPGeoPoint &point(media.c_messageMediaGeo().vgeo);
|
||||
const MTPGeoPoint &point(media->c_messageMediaGeo().vgeo);
|
||||
if (point.type() == mtpc_geoPoint) {
|
||||
const MTPDgeoPoint &d(point.c_geoPoint());
|
||||
_media = new HistoryImageLink(qsl("location:%1,%2").arg(d.vlat.v).arg(d.vlong.v));
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaVenue: {
|
||||
const MTPDmessageMediaVenue &d(media.c_messageMediaVenue());
|
||||
const MTPDmessageMediaVenue &d(media->c_messageMediaVenue());
|
||||
if (d.vgeo.type() == mtpc_geoPoint) {
|
||||
const MTPDgeoPoint &g(d.vgeo.c_geoPoint());
|
||||
_media = new HistoryImageLink(qsl("location:%1,%2").arg(g.vlat.v).arg(g.vlong.v), qs(d.vtitle), qs(d.vaddress));
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaPhoto: {
|
||||
const MTPDmessageMediaPhoto &photo(media.c_messageMediaPhoto());
|
||||
const MTPDmessageMediaPhoto &photo(media->c_messageMediaPhoto());
|
||||
if (photo.vphoto.type() == mtpc_photo) {
|
||||
_media = new HistoryPhoto(photo.vphoto.c_photo(), qs(photo.vcaption), this);
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaVideo: {
|
||||
const MTPDmessageMediaVideo &video(media.c_messageMediaVideo());
|
||||
const MTPDmessageMediaVideo &video(media->c_messageMediaVideo());
|
||||
if (video.vvideo.type() == mtpc_video) {
|
||||
_media = new HistoryVideo(video.vvideo.c_video(), qs(video.vcaption), this);
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaAudio: {
|
||||
const MTPAudio &audio(media.c_messageMediaAudio().vaudio);
|
||||
const MTPAudio &audio(media->c_messageMediaAudio().vaudio);
|
||||
if (audio.type() == mtpc_audio) {
|
||||
_media = new HistoryAudio(audio.c_audio());
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaDocument: {
|
||||
const MTPDocument &document(media.c_messageMediaDocument().vdocument);
|
||||
const MTPDocument &document(media->c_messageMediaDocument().vdocument);
|
||||
if (document.type() == mtpc_document) {
|
||||
DocumentData *doc = App::feedDocument(document);
|
||||
return initMediaFromDocument(doc);
|
||||
}
|
||||
} break;
|
||||
case mtpc_messageMediaWebPage: {
|
||||
const MTPWebPage &d(media.c_messageMediaWebPage().vwebpage);
|
||||
const MTPWebPage &d(media->c_messageMediaWebPage().vwebpage);
|
||||
switch (d.type()) {
|
||||
case mtpc_webPageEmpty: initMediaFromText(currentText); break;
|
||||
case mtpc_webPagePending: {
|
||||
@ -5125,16 +5366,6 @@ void HistoryMessage::initMediaFromDocument(DocumentData *doc) {
|
||||
_media->regItem(this);
|
||||
}
|
||||
|
||||
void HistoryMessage::initDimensions(const QString &text) {
|
||||
if (!_media || !text.isEmpty()) { // !justMedia()
|
||||
if (_media && _media->isDisplayed()) {
|
||||
_text.setText(st::msgFont, text, itemTextParseOptions(this));
|
||||
} else {
|
||||
_text.setText(st::msgFont, text + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), itemTextParseOptions(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryMessage::initDimensions(const HistoryItem *parent) {
|
||||
if (justMedia()) {
|
||||
_media->initDimensions(this);
|
||||
@ -5147,19 +5378,13 @@ void HistoryMessage::initDimensions(const HistoryItem *parent) {
|
||||
if (_media) {
|
||||
_media->initDimensions(this);
|
||||
if (_media->isDisplayed() && _text.hasSkipBlock()) {
|
||||
QString was = HistoryMessage::selectedText(FullItemSel);
|
||||
if (!was.isEmpty()) {
|
||||
_text.setText(st::msgFont, was, itemTextParseOptions(this)); // without date skip
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
_text.removeSkipBlock();
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
} else if (!_media->isDisplayed() && !_text.hasSkipBlock()) {
|
||||
QString was = HistoryMessage::selectedText(FullItemSel);
|
||||
if (!was.isEmpty()) {
|
||||
_text.setText(st::msgFont, was + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), itemTextParseOptions(this)); // without date skip
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
_text.setSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y());
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
if (_media->isDisplayed()) {
|
||||
int32 maxw = _media->maxWidth() + st::msgPadding.left() + st::msgPadding.right();
|
||||
@ -5191,6 +5416,10 @@ QString HistoryMessage::selectedText(uint32 selection) const {
|
||||
return _text.original(selectedFrom, selectedTo);
|
||||
}
|
||||
|
||||
LinksInText HistoryMessage::textLinks() const {
|
||||
return _text.calcLinksInText();
|
||||
}
|
||||
|
||||
QString HistoryMessage::inDialogsText() const {
|
||||
QString result = _media ? _media->inDialogsText() : QString();
|
||||
return result.isEmpty() ? _text.original(0, 0xFFFF, false) : result;
|
||||
@ -5200,8 +5429,9 @@ HistoryMedia *HistoryMessage::getMedia(bool inOverview) const {
|
||||
return _media;
|
||||
}
|
||||
|
||||
void HistoryMessage::setMedia(const MTPmessageMedia &media) {
|
||||
if ((!_media || _media->isImageLink()) && media.type() == mtpc_messageMediaEmpty) return;
|
||||
void HistoryMessage::setMedia(const MTPMessageMedia *media) {
|
||||
if ((!_media || _media->isImageLink()) && (!media || media->type() == mtpc_messageMediaEmpty)) return;
|
||||
|
||||
bool mediaWasDisplayed = false;
|
||||
if (_media) {
|
||||
mediaWasDisplayed = _media->isDisplayed();
|
||||
@ -5211,24 +5441,48 @@ void HistoryMessage::setMedia(const MTPmessageMedia &media) {
|
||||
QString t;
|
||||
initMedia(media, t);
|
||||
if (_media && _media->isDisplayed() && !mediaWasDisplayed) {
|
||||
QString was = HistoryMessage::selectedText(FullItemSel);
|
||||
if (!was.isEmpty()) {
|
||||
_text.setText(st::msgFont, was, itemTextParseOptions(this)); // without date skip
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
_text.removeSkipBlock();
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
} else if (mediaWasDisplayed && (!_media || !_media->isDisplayed())) {
|
||||
QString was = HistoryMessage::selectedText(FullItemSel);
|
||||
if (!was.isEmpty()) {
|
||||
_text.setText(st::msgFont, was + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), itemTextParseOptions(this)); // without date skip
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
_text.setSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y());
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
initDimensions(0);
|
||||
if (App::main()) App::main()->itemResized(this);
|
||||
}
|
||||
|
||||
void HistoryMessage::setText(const QString &text, const LinksInText &links) {
|
||||
if (!_media || !text.isEmpty()) { // !justMedia()
|
||||
if (_media && _media->isDisplayed()) {
|
||||
_text.setMarkedText(st::msgFont, text, links, itemTextParseOptions(this));
|
||||
} else {
|
||||
_text.setMarkedText(st::msgFont, text + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), links, itemTextParseOptions(this));
|
||||
}
|
||||
if (id > 0) {
|
||||
for (int32 i = 0, l = links.size(); i != l; ++i) {
|
||||
if (links.at(i).type == LinkInTextUrl || links.at(i).type == LinkInTextCustomUrl || links.at(i).type == LinkInTextEmail) {
|
||||
_flags |= MTPDmessage_flag_HAS_TEXT_LINKS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_textWidth = 0;
|
||||
_textHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryMessage::getTextWithLinks(QString &text, LinksInText &links) {
|
||||
if (_text.isEmpty()) return;
|
||||
links = _text.calcLinksInText();
|
||||
text = _text.original();
|
||||
}
|
||||
|
||||
bool HistoryMessage::textHasLinks() {
|
||||
return _text.hasLinks();
|
||||
}
|
||||
|
||||
void HistoryMessage::draw(QPainter &p, uint32 selection) const {
|
||||
textstyleSet(&(out() ? st::outTextStyle : st::inTextStyle));
|
||||
|
||||
@ -5333,6 +5587,8 @@ void HistoryMessage::drawMessageText(QPainter &p, const QRect &trect, uint32 sel
|
||||
}
|
||||
|
||||
int32 HistoryMessage::resize(int32 width, bool dontRecountText, const HistoryItem *parent) {
|
||||
if (width < st::msgMinWidth) return _height;
|
||||
|
||||
width -= st::msgMargin.left() + st::msgMargin.right();
|
||||
if (justMedia()) {
|
||||
_height = _media->resize(width, dontRecountText, this);
|
||||
@ -5538,7 +5794,7 @@ HistoryMessage::~HistoryMessage() {
|
||||
}
|
||||
}
|
||||
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.has_entities() ? linksFromMTP(msg.ventities.c_vector().v) : LinksInText(), msg.has_media() ? (&msg.vmedia) : 0)
|
||||
, fwdDate(::date(msg.vfwd_date))
|
||||
, fwdFrom(App::user(msg.vfwd_from_id.v))
|
||||
, fwdFromVersion(fwdFrom->nameVersion)
|
||||
@ -5547,7 +5803,7 @@ HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, const
|
||||
fwdNameUpdated();
|
||||
}
|
||||
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg) : HistoryMessage(history, block, id, ((history->peer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0) | (msg->getMedia() && (msg->getMedia()->type() == MediaTypeAudio/* || msg->getMedia()->type() == MediaTypeVideo*/) ? MTPDmessage_flag_media_unread : 0), ::date(unixtime()), MTP::authedId(), msg->justMedia() ? QString() : msg->HistoryMessage::selectedText(FullItemSel), msg->getMedia())
|
||||
HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId id, HistoryMessage *msg) : HistoryMessage(history, block, id, ((history->peer->input.type() != mtpc_inputPeerSelf) ? (MTPDmessage_flag_out | MTPDmessage_flag_unread) : 0) | (msg->getMedia() && (msg->getMedia()->type() == MediaTypeAudio/* || msg->getMedia()->type() == MediaTypeVideo*/) ? MTPDmessage_flag_media_unread : 0), ::date(unixtime()), MTP::authedId(), msg->justMedia() ? QString() : msg->HistoryMessage::selectedText(FullItemSel), msg->HistoryMessage::textLinks(), msg->getMedia())
|
||||
, fwdDate(msg->dateForwarded())
|
||||
, fwdFrom(msg->fromForwarded())
|
||||
, fwdFromVersion(fwdFrom->nameVersion)
|
||||
@ -5734,7 +5990,7 @@ void HistoryForwarded::getSymbol(uint16 &symbol, bool &after, bool &upon, int32
|
||||
return HistoryMessage::getSymbol(symbol, after, upon, x, y);
|
||||
}
|
||||
|
||||
HistoryReply::HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.vmedia)
|
||||
HistoryReply::HistoryReply(History *history, HistoryBlock *block, const MTPDmessage &msg) : HistoryMessage(history, block, msg.vid.v, msg.vflags.v, ::date(msg.vdate), msg.vfrom_id.v, textClean(qs(msg.vmessage)), msg.has_entities() ? linksFromMTP(msg.ventities.c_vector().v) : LinksInText(), msg.has_media() ? (&msg.vmedia) : 0)
|
||||
, replyToMsgId(msg.vreply_to_msg_id.v)
|
||||
, replyToMsg(0)
|
||||
, replyToVersion(0)
|
||||
|
@ -107,6 +107,7 @@ enum MediaOverviewType {
|
||||
OverviewDocuments,
|
||||
OverviewAudios,
|
||||
OverviewAudioDocuments,
|
||||
OverviewLinks,
|
||||
|
||||
OverviewCount
|
||||
};
|
||||
@ -116,7 +117,7 @@ inline MediaOverviewType mediaToOverviewType(HistoryMediaType t) {
|
||||
case MediaTypePhoto: return OverviewPhotos;
|
||||
case MediaTypeVideo: return OverviewVideos;
|
||||
case MediaTypeDocument: return OverviewDocuments;
|
||||
// case MediaTypeSticker: return OverviewDocuments;
|
||||
// case MediaTypeSticker: return OverviewDocuments;
|
||||
case MediaTypeAudio: return OverviewAudios;
|
||||
}
|
||||
return OverviewCount;
|
||||
@ -129,6 +130,7 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||
case OverviewDocuments: return MTP_inputMessagesFilterDocument();
|
||||
case OverviewAudios: return MTP_inputMessagesFilterAudio();
|
||||
case OverviewAudioDocuments: return MTP_inputMessagesFilterAudioDocuments();
|
||||
case OverviewLinks: return MTP_inputMessagesFilterUrl();
|
||||
default: type = OverviewCount; break;
|
||||
}
|
||||
return MTPMessagesFilter();
|
||||
@ -183,6 +185,8 @@ struct History : public QList<HistoryBlock*> {
|
||||
void addToBack(const QVector<MTPMessage> &slice);
|
||||
void createInitialDateBlock(const QDateTime &date);
|
||||
HistoryItem *doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *adding, bool newMsg);
|
||||
void addToOverview(HistoryItem *item, MediaOverviewType type);
|
||||
bool addToOverviewFront(HistoryItem *item, MediaOverviewType type);
|
||||
|
||||
void newItemAdded(HistoryItem *item);
|
||||
void unregTyping(UserData *from);
|
||||
@ -723,6 +727,9 @@ public:
|
||||
bool hasReplyMarkup() const {
|
||||
return _flags & MTPDmessage::flag_reply_markup;
|
||||
}
|
||||
bool hasTextLinks() const {
|
||||
return _flags & MTPDmessage_flag_HAS_TEXT_LINKS;
|
||||
}
|
||||
virtual bool needCheck() const {
|
||||
return true;
|
||||
}
|
||||
@ -773,7 +780,14 @@ public:
|
||||
virtual HistoryMedia *getMedia(bool inOverview = false) const {
|
||||
return 0;
|
||||
}
|
||||
virtual void setMedia(const MTPmessageMedia &media) {
|
||||
virtual void setMedia(const MTPMessageMedia *media) {
|
||||
}
|
||||
virtual void setText(const QString &text, const LinksInText &links) {
|
||||
}
|
||||
virtual void getTextWithLinks(QString &text, LinksInText &links) {
|
||||
}
|
||||
virtual bool textHasLinks() {
|
||||
return false;
|
||||
}
|
||||
virtual QString time() const {
|
||||
return QString();
|
||||
@ -989,7 +1003,7 @@ private:
|
||||
Text _caption;
|
||||
|
||||
QString _size;
|
||||
int32 _thumbw, _thumbx, _thumby;
|
||||
int32 _thumbw;
|
||||
|
||||
mutable QString _dldTextCache, _uplTextCache;
|
||||
mutable int32 _dldDone, _uplDone;
|
||||
@ -1170,20 +1184,26 @@ public:
|
||||
void unregItem(HistoryItem *item);
|
||||
|
||||
bool hasReplyPreview() const {
|
||||
return data->photo && !data->photo->thumb->isNull();
|
||||
return (data->photo && !data->photo->thumb->isNull()) || (data->doc && !data->doc->thumb->isNull());
|
||||
}
|
||||
ImagePtr replyPreview();
|
||||
|
||||
WebPageData *webpage() {
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
WebPageData *data;
|
||||
TextLinkPtr _openl, _photol;
|
||||
TextLinkPtr _openl, _attachl;
|
||||
bool _asArticle;
|
||||
|
||||
Text _title, _description;
|
||||
int32 _siteNameWidth;
|
||||
|
||||
QString _duration;
|
||||
int32 _durationWidth;
|
||||
QString _duration, _docName, _docSize;
|
||||
int32 _durationWidth, _docNameWidth, _docThumbWidth;
|
||||
mutable QString _docDownloadTextCache;
|
||||
mutable int32 _docDownloadDone;
|
||||
|
||||
int16 _pixw, _pixh;
|
||||
};
|
||||
@ -1274,16 +1294,15 @@ class HistoryMessage : public HistoryItem {
|
||||
public:
|
||||
|
||||
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media);
|
||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *media);
|
||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, const MTPMessageMedia *media);
|
||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, HistoryMedia *media);
|
||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc);
|
||||
|
||||
void initTime();
|
||||
void initMedia(const MTPMessageMedia &media, QString ¤tText);
|
||||
void initMedia(const MTPMessageMedia *media, QString ¤tText);
|
||||
void initMediaFromText(QString ¤tText);
|
||||
void initMediaFromDocument(DocumentData *doc);
|
||||
void initDimensions(const HistoryItem *parent = 0);
|
||||
void initDimensions(const QString &text);
|
||||
void fromNameUpdated() const;
|
||||
|
||||
bool justMedia() const {
|
||||
@ -1317,9 +1336,13 @@ public:
|
||||
}
|
||||
|
||||
QString selectedText(uint32 selection) const;
|
||||
LinksInText textLinks() const;
|
||||
QString inDialogsText() const;
|
||||
HistoryMedia *getMedia(bool inOverview = false) const;
|
||||
void setMedia(const MTPmessageMedia &media);
|
||||
void setMedia(const MTPMessageMedia *media);
|
||||
void setText(const QString &text, const LinksInText &links);
|
||||
void getTextWithLinks(QString &text, LinksInText &links);
|
||||
bool textHasLinks();
|
||||
|
||||
QString time() const {
|
||||
return _time;
|
||||
@ -1554,3 +1577,5 @@ protected:
|
||||
QString text;
|
||||
bool freezed;
|
||||
};
|
||||
|
||||
const TextParseOptions &itemTextParseOptions(History *h, UserData *f);
|
||||
|
@ -559,10 +559,10 @@ void HistoryList::onDragExec() {
|
||||
QDrag *drag = new QDrag(App::wnd());
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
|
||||
if (dragSticker || dragByDate) {
|
||||
mimeData->setData(qsl("application/x-td-forward-pressed"), "1");
|
||||
} else {
|
||||
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument || lnkContact) {
|
||||
mimeData->setData(qsl("application/x-td-forward-pressed-link"), "1");
|
||||
} else {
|
||||
mimeData->setData(qsl("application/x-td-forward-pressed"), "1");
|
||||
}
|
||||
if (lnkDocument) {
|
||||
QString already = static_cast<DocumentOpenLink*>(textlnkDown().data())->document()->already(true);
|
||||
@ -1346,7 +1346,6 @@ void HistoryList::onUpdateSelected() {
|
||||
if (_dragItem && _dragItem->detached()) {
|
||||
dragActionCancel();
|
||||
}
|
||||
linkTipTimer.start(1000);
|
||||
|
||||
Qt::CursorShape cur = style::cur_default;
|
||||
HistoryCursorState cursorState = HistoryDefaultCursorState;
|
||||
@ -1373,7 +1372,7 @@ void HistoryList::onUpdateSelected() {
|
||||
}
|
||||
}
|
||||
textlnkOver(lnk);
|
||||
QToolTip::showText(_dragPos, QString(), App::wnd());
|
||||
QToolTip::hideText();
|
||||
App::hoveredLinkItem((lnk && !lnkInDesc) ? item : 0);
|
||||
if (textlnkOver()) {
|
||||
if (App::hoveredLinkItem()) {
|
||||
@ -1383,6 +1382,12 @@ void HistoryList::onUpdateSelected() {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lnk || cursorState == HistoryInDateCursorState) {
|
||||
linkTipTimer.start(1000);
|
||||
}
|
||||
if (_dragCursorState == HistoryInDateCursorState && cursorState != HistoryInDateCursorState) {
|
||||
QToolTip::hideText();
|
||||
}
|
||||
|
||||
if (_dragAction == NoDrag) {
|
||||
_dragCursorState = cursorState;
|
||||
@ -1544,8 +1549,15 @@ void HistoryList::applyDragSelection(SelectedItems *toItems) const {
|
||||
|
||||
void HistoryList::showLinkTip() {
|
||||
TextLinkPtr lnk = textlnkOver();
|
||||
int32 dd = QApplication::startDragDistance();
|
||||
QPoint dp(mapFromGlobal(_dragPos));
|
||||
QRect r(dp.x() - dd, dp.y() - dd, 2 * dd, 2 * dd);
|
||||
if (lnk && !lnk->fullDisplayed()) {
|
||||
QToolTip::showText(_dragPos, lnk->readable(), App::wnd());
|
||||
QToolTip::showText(_dragPos, lnk->readable(), this, r);
|
||||
} else if (_dragCursorState == HistoryInDateCursorState && _dragAction == NoDrag) {
|
||||
if (App::hoveredItem()) {
|
||||
QToolTip::showText(_dragPos, App::hoveredItem()->date.toString(QLocale::system().dateTimeFormat(QLocale::LongFormat)), this, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1873,7 +1885,10 @@ void BotKeyboard::showCommandTip() {
|
||||
if (_sel >= 0) {
|
||||
int row = (_sel / MatrixRowShift), col = _sel % MatrixRowShift;
|
||||
if (!_btns.at(row).at(col).full) {
|
||||
QToolTip::showText(_lastMousePos, _btns.at(row).at(col).cmd);
|
||||
int32 dd = QApplication::startDragDistance();
|
||||
QPoint dp(mapFromGlobal(_lastMousePos));
|
||||
QRect r(dp.x() - dd, dp.y() - dd, 2 * dd, 2 * dd);
|
||||
QToolTip::showText(_lastMousePos, _btns.at(row).at(col).cmd, this, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1899,7 +1914,7 @@ void BotKeyboard::updateSelected() {
|
||||
if (newSel >= 0) break;
|
||||
}
|
||||
if (newSel != _sel) {
|
||||
QToolTip::showText(_lastMousePos, QString(), App::wnd());
|
||||
QToolTip::hideText();
|
||||
if (newSel < 0) {
|
||||
setCursor(style::cur_default);
|
||||
} else if (_sel < 0) {
|
||||
@ -2712,19 +2727,17 @@ void HistoryWidget::showPeerHistory(const PeerId &peerId, MsgId showAtMsgId) {
|
||||
bool canShowNow = _history->isReadyFor(showAtMsgId, true);
|
||||
if (!canShowNow) {
|
||||
delayedShowAt(showAtMsgId);
|
||||
return;
|
||||
} else {
|
||||
clearDelayedShowAt();
|
||||
if (_replyReturn && _replyReturn->id == showAtMsgId) {
|
||||
calcNextReplyReturn();
|
||||
}
|
||||
|
||||
_showAtMsgId = showAtMsgId;
|
||||
_histInited = false;
|
||||
|
||||
historyLoaded();
|
||||
}
|
||||
|
||||
clearDelayedShowAt();
|
||||
if (_replyReturn && _replyReturn->id == showAtMsgId) {
|
||||
calcNextReplyReturn();
|
||||
}
|
||||
|
||||
_showAtMsgId = showAtMsgId;
|
||||
_histInited = false;
|
||||
|
||||
historyLoaded();
|
||||
|
||||
emit peerShown(_peer);
|
||||
App::main()->topBar()->update();
|
||||
update();
|
||||
@ -3049,6 +3062,24 @@ void HistoryWidget::updateControlsVisibility() {
|
||||
resizeEvent(0);
|
||||
update();
|
||||
}
|
||||
} else {
|
||||
_attachMention.hide();
|
||||
_send.hide();
|
||||
_unblock.hide();
|
||||
_botStart.hide();
|
||||
_attachDocument.hide();
|
||||
_attachPhoto.hide();
|
||||
_attachEmoji.hide();
|
||||
_kbShow.hide();
|
||||
_kbHide.hide();
|
||||
_cmdStart.hide();
|
||||
_attachType.hide();
|
||||
_emojiPan.hide();
|
||||
if (!_field.isHidden()) {
|
||||
_field.hide();
|
||||
resizeEvent(0);
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3416,7 +3447,7 @@ void HistoryWidget::shareContact(const PeerId &peer, const QString &phone, const
|
||||
fastShowAtEnd(h);
|
||||
|
||||
PeerData *p = App::peer(peer);
|
||||
int32 flags = newMessageFlags(p); // unread, out
|
||||
int32 flags = newMessageFlags(p) | MTPDmessage::flag_media; // unread, out
|
||||
|
||||
bool lastKeyboardUsed = lastForceReplyReplied(replyTo);
|
||||
|
||||
@ -4296,14 +4327,15 @@ void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
|
||||
|
||||
fastShowAtEnd(h);
|
||||
|
||||
int32 flags = newMessageFlags(h->peer); // unread, out
|
||||
int32 flags = newMessageFlags(h->peer) | MTPDmessage::flag_media; // unread, out
|
||||
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
if (img.type == ToPreparePhoto) {
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string("")), MTPnullMarkup, MTPnullEntities));
|
||||
} else if (img.type == ToPrepareDocument) {
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities));
|
||||
} else if (img.type == ToPrepareAudio) {
|
||||
h->addToBack(MTP_message(MTP_int(flags | MTPDmessage_flag_media_unread), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities));
|
||||
flags |= MTPDmessage_flag_media_unread;
|
||||
h->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(img.peer), MTPint(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities));
|
||||
}
|
||||
|
||||
if (_peer && img.peer == _peer->id) {
|
||||
@ -4902,7 +4934,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
|
||||
bool lastKeyboardUsed = lastForceReplyReplied();
|
||||
|
||||
bool out = (_peer->input.type() != mtpc_inputPeerSelf), unread = (_peer->input.type() != mtpc_inputPeerSelf);
|
||||
int32 flags = newMessageFlags(_peer); // unread, out
|
||||
int32 flags = newMessageFlags(_peer) | MTPDmessage::flag_media; // unread, out
|
||||
int32 sendFlags = 0;
|
||||
if (replyToId()) {
|
||||
flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
@ -5114,18 +5146,25 @@ void HistoryWidget::updatePreview() {
|
||||
if (_previewData->title.isEmpty()) {
|
||||
if (_previewData->description.isEmpty()) {
|
||||
title = _previewData->author;
|
||||
desc = _previewData->url;
|
||||
desc = ((_previewData->doc && !_previewData->doc->name.isEmpty()) ? _previewData->doc->name : _previewData->url);
|
||||
} else {
|
||||
title = _previewData->description;
|
||||
desc = _previewData->author.isEmpty() ? _previewData->url : _previewData->author;
|
||||
desc = _previewData->author.isEmpty() ? ((_previewData->doc && !_previewData->doc->name.isEmpty()) ? _previewData->doc->name : _previewData->url) : _previewData->author;
|
||||
}
|
||||
} else {
|
||||
title = _previewData->title;
|
||||
desc = _previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? _previewData->url : _previewData->author) : _previewData->description;
|
||||
desc = _previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? ((_previewData->doc && !_previewData->doc->name.isEmpty()) ? _previewData->doc->name : _previewData->url) : _previewData->author) : _previewData->description;
|
||||
}
|
||||
} else {
|
||||
title = _previewData->siteName;
|
||||
desc = _previewData->title.isEmpty() ? (_previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? _previewData->url : _previewData->author) : _previewData->description) : _previewData->title;
|
||||
desc = _previewData->title.isEmpty() ? (_previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? ((_previewData->doc && !_previewData->doc->name.isEmpty()) ? _previewData->doc->name : _previewData->url) : _previewData->author) : _previewData->description) : _previewData->title;
|
||||
}
|
||||
if (title.isEmpty()) {
|
||||
if (_previewData->photo) {
|
||||
title = lang(lng_attach_photo);
|
||||
} else if (_previewData->doc) {
|
||||
title = lang(lng_attach_file);
|
||||
}
|
||||
}
|
||||
_previewTitle.setText(st::msgServiceNameFont, title, _textNameOptions);
|
||||
_previewDescription.setText(st::msgFont, desc, _textDlgOptions);
|
||||
@ -5407,8 +5446,8 @@ void HistoryWidget::drawField(Painter &p) {
|
||||
if (drawPreview) {
|
||||
int32 previewLeft = st::replySkip + st::webPageLeft;
|
||||
p.fillRect(st::replySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor->b);
|
||||
if (_previewData->photo && !_previewData->photo->thumb->isNull()) {
|
||||
ImagePtr replyPreview = _previewData->photo->makeReplyPreview();
|
||||
if ((_previewData->photo && !_previewData->photo->thumb->isNull()) || (_previewData->doc && !_previewData->doc->thumb->isNull())) {
|
||||
ImagePtr replyPreview = _previewData->photo ? _previewData->photo->makeReplyPreview() : _previewData->doc->makeReplyPreview();
|
||||
if (!replyPreview->isNull()) {
|
||||
QRect to(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
|
||||
if (replyPreview->width() == replyPreview->height()) {
|
||||
|
@ -43,7 +43,9 @@ namespace {
|
||||
countryForReg = nearest.vcountry.c_string().v.c_str();
|
||||
emit signalEmitOn->countryChanged();
|
||||
}
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (App::app()) App::app()->startUpdateCheck();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,6 +65,7 @@ visibilityChanging(0),
|
||||
_callTimeout(60),
|
||||
_registered(false),
|
||||
_hasRecovery(false),
|
||||
_codeByTelegram(false),
|
||||
_back(this, st::setClose),
|
||||
_backFrom(0), _backTo(0) {
|
||||
setGeometry(QRect(0, st::titleHeight, wnd->width(), wnd->height() - st::titleHeight));
|
||||
@ -333,6 +336,11 @@ void IntroWidget::setPwdHint(const QString &hint) {
|
||||
_pwdHint = hint;
|
||||
}
|
||||
|
||||
void IntroWidget::setCodeByTelegram(bool byTelegram) {
|
||||
_codeByTelegram = byTelegram;
|
||||
if (code) code->updateDescText();
|
||||
}
|
||||
|
||||
void IntroWidget::setCallTimeout(int32 callTimeout) {
|
||||
_callTimeout = callTimeout;
|
||||
}
|
||||
@ -365,6 +373,10 @@ const QString &IntroWidget::getPwdHint() const {
|
||||
return _pwdHint;
|
||||
}
|
||||
|
||||
bool IntroWidget::codeByTelegram() const {
|
||||
return _codeByTelegram;
|
||||
}
|
||||
|
||||
void IntroWidget::resizeEvent(QResizeEvent *e) {
|
||||
QRect r(innerRect());
|
||||
if (steps) steps->setGeometry(r);
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
void setPwdSalt(const QByteArray &salt);
|
||||
void setHasRecovery(bool hasRecovery);
|
||||
void setPwdHint(const QString &hint);
|
||||
void setCodeByTelegram(bool byTelegram);
|
||||
|
||||
const QString &getPhone() const;
|
||||
const QString &getPhoneHash() const;
|
||||
@ -60,6 +61,7 @@ public:
|
||||
const QByteArray &getPwdSalt() const;
|
||||
bool getHasRecovery() const;
|
||||
const QString &getPwdHint() const;
|
||||
bool codeByTelegram() const;
|
||||
|
||||
void finish(const MTPUser &user, const QImage &photo = QImage());
|
||||
|
||||
@ -114,7 +116,7 @@ private:
|
||||
QString _code;
|
||||
|
||||
QByteArray _pwdSalt;
|
||||
bool _hasRecovery;
|
||||
bool _hasRecovery, _codeByTelegram;
|
||||
QString _pwdHint;
|
||||
|
||||
QString _firstname, _lastname;
|
||||
|
@ -69,6 +69,9 @@ void CodeInput::correctValue(QKeyEvent *e, const QString &was) {
|
||||
|
||||
IntroCode::IntroCode(IntroWidget *parent) : IntroStage(parent), errorAlpha(0),
|
||||
next(this, lang(lng_intro_next), st::btnIntroNext),
|
||||
_desc(st::introTextSize.width()),
|
||||
_noTelegramCode(this, lang(lng_code_no_telegram), st::introLink),
|
||||
_noTelegramCodeRequestId(0),
|
||||
code(this, st::inpIntroCode, lang(lng_code_ph)), waitTillCall(intro()->getCallTimeout()) {
|
||||
setVisible(false);
|
||||
setGeometry(parent->innerRect());
|
||||
@ -78,6 +81,24 @@ IntroCode::IntroCode(IntroWidget *parent) : IntroStage(parent), errorAlpha(0),
|
||||
connect(&code, SIGNAL(changed()), this, SLOT(onInputChange()));
|
||||
connect(&callTimer, SIGNAL(timeout()), this, SLOT(onSendCall()));
|
||||
connect(&checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
|
||||
connect(&_noTelegramCode, SIGNAL(clicked()), this, SLOT(onNoTelegramCode()));
|
||||
|
||||
updateDescText();
|
||||
}
|
||||
|
||||
void IntroCode::updateDescText() {
|
||||
_desc.setRichText(st::introFont, lang(intro()->codeByTelegram() ? lng_code_telegram : lng_code_desc));
|
||||
if (intro()->codeByTelegram()) {
|
||||
_noTelegramCode.show();
|
||||
callTimer.stop();
|
||||
} else {
|
||||
_noTelegramCode.hide();
|
||||
waitTillCall = intro()->getCallTimeout();
|
||||
if (!callTimer.isActive()) {
|
||||
callTimer.start(1000);
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
void IntroCode::paintEvent(QPaintEvent *e) {
|
||||
@ -87,21 +108,25 @@ void IntroCode::paintEvent(QPaintEvent *e) {
|
||||
if (!trivial) {
|
||||
p.setClipRect(e->rect());
|
||||
}
|
||||
bool codeByTelegram = intro()->codeByTelegram();
|
||||
if (trivial || e->rect().intersects(textRect)) {
|
||||
p.setFont(st::introHeaderFont->f);
|
||||
p.drawText(textRect, intro()->getPhone(), style::al_top);
|
||||
p.setFont(st::introFont->f);
|
||||
p.drawText(textRect, lang(lng_code_desc), style::al_bottom);
|
||||
_desc.draw(p, textRect.x(), textRect.y() + textRect.height() - 2 * st::introFont->height, textRect.width(), style::al_top);
|
||||
}
|
||||
QString callText = lang(lng_code_calling);
|
||||
if (waitTillCall >= 3600) {
|
||||
callText = lng_code_call(lt_minutes, qsl("%1:%2").arg(waitTillCall / 3600).arg((waitTillCall / 60) % 60, 2, 10, QChar('0')), lt_seconds, qsl("%1").arg(waitTillCall % 60, 2, 10, QChar('0')));
|
||||
} else if (waitTillCall > 0) {
|
||||
callText = lng_code_call(lt_minutes, QString::number(waitTillCall / 60), lt_seconds, qsl("%1").arg(waitTillCall % 60, 2, 10, QChar('0')));
|
||||
} else if (waitTillCall < 0) {
|
||||
callText = lang(lng_code_called);
|
||||
if (codeByTelegram) {
|
||||
} else {
|
||||
QString callText = lang(lng_code_calling);
|
||||
if (waitTillCall >= 3600) {
|
||||
callText = lng_code_call(lt_minutes, qsl("%1:%2").arg(waitTillCall / 3600).arg((waitTillCall / 60) % 60, 2, 10, QChar('0')), lt_seconds, qsl("%1").arg(waitTillCall % 60, 2, 10, QChar('0')));
|
||||
} else if (waitTillCall > 0) {
|
||||
callText = lng_code_call(lt_minutes, QString::number(waitTillCall / 60), lt_seconds, qsl("%1").arg(waitTillCall % 60, 2, 10, QChar('0')));
|
||||
} else if (waitTillCall < 0) {
|
||||
callText = lang(lng_code_called);
|
||||
}
|
||||
p.drawText(QRect(textRect.left(), code.y() + code.height() + st::introCallSkip, st::introTextSize.width(), st::introErrHeight), callText, style::al_center);
|
||||
}
|
||||
p.drawText(QRect(textRect.left(), code.y() + code.height() + st::introCallSkip, st::introTextSize.width(), st::introErrHeight), callText, style::al_center);
|
||||
if (animating() || error.length()) {
|
||||
p.setOpacity(errorAlpha.current());
|
||||
p.setFont(st::introErrFont->f);
|
||||
@ -116,6 +141,7 @@ void IntroCode::resizeEvent(QResizeEvent *e) {
|
||||
code.move((width() - code.width()) / 2, st::introTextTop + st::introTextSize.height() + st::introCountry.top);
|
||||
}
|
||||
textRect = QRect((width() - st::introTextSize.width()) / 2, st::introTextTop, st::introTextSize.width(), st::introTextSize.height());
|
||||
_noTelegramCode.move(textRect.left() + (st::introTextSize.width() - _noTelegramCode.width()) / 2, code.y() + code.height() + st::introCallSkip + (st::introErrHeight - _noTelegramCode.height()) / 2);
|
||||
}
|
||||
|
||||
void IntroCode::showError(const QString &err) {
|
||||
@ -150,7 +176,9 @@ bool IntroCode::animStep(float64 ms) {
|
||||
|
||||
void IntroCode::activate() {
|
||||
waitTillCall = intro()->getCallTimeout();
|
||||
callTimer.start(1000);
|
||||
if (!intro()->codeByTelegram()) {
|
||||
callTimer.start(1000);
|
||||
}
|
||||
error = "";
|
||||
errorAlpha = anim::fvalue(0);
|
||||
sentCode = QString();
|
||||
@ -300,6 +328,31 @@ void IntroCode::onSubmitCode(bool force) {
|
||||
sentRequest = MTP::send(MTPauth_SignIn(MTP_string(intro()->getPhone()), MTP_string(intro()->getPhoneHash()), MTP_string(sentCode)), rpcDone(&IntroCode::codeSubmitDone), rpcFail(&IntroCode::codeSubmitFail));
|
||||
}
|
||||
|
||||
void IntroCode::onNoTelegramCode() {
|
||||
if (_noTelegramCodeRequestId) return;
|
||||
_noTelegramCodeRequestId = MTP::send(MTPauth_SendSms(MTP_string(intro()->getPhone()), MTP_string(intro()->getPhoneHash())), rpcDone(&IntroCode::noTelegramCodeDone), rpcFail(&IntroCode::noTelegramCodeFail));
|
||||
}
|
||||
|
||||
void IntroCode::noTelegramCodeDone(const MTPBool &result) {
|
||||
intro()->setCodeByTelegram(false);
|
||||
updateDescText();
|
||||
}
|
||||
|
||||
bool IntroCode::noTelegramCodeFail(const RPCError &error) {
|
||||
if (error.type().startsWith(qsl("FLOOD_WAIT_"))) {
|
||||
showError(lang(lng_flood_error));
|
||||
code.setFocus();
|
||||
return true;
|
||||
}
|
||||
if (cDebug()) { // internal server error
|
||||
showError(error.type() + ": " + error.description());
|
||||
} else {
|
||||
showError(lang(lng_server_error));
|
||||
}
|
||||
code.setFocus();
|
||||
return false;
|
||||
}
|
||||
|
||||
void IntroCode::onNext() {
|
||||
onSubmitCode();
|
||||
}
|
||||
|
@ -64,9 +64,12 @@ public:
|
||||
void codeSubmitDone(const MTPauth_Authorization &result);
|
||||
bool codeSubmitFail(const RPCError &error);
|
||||
|
||||
void updateDescText();
|
||||
|
||||
public slots:
|
||||
|
||||
void onSubmitCode(bool force = false);
|
||||
void onNoTelegramCode();
|
||||
void onInputChange();
|
||||
void onSendCall();
|
||||
void onCheckRequest();
|
||||
@ -84,8 +87,14 @@ private:
|
||||
|
||||
FlatButton next;
|
||||
|
||||
Text _desc;
|
||||
LinkButton _noTelegramCode;
|
||||
mtpRequestId _noTelegramCodeRequestId;
|
||||
QRect textRect;
|
||||
|
||||
void noTelegramCodeDone(const MTPBool &result);
|
||||
bool noTelegramCodeFail(const RPCError &result);
|
||||
|
||||
CodeInput code;
|
||||
QString sentCode;
|
||||
mtpRequestId sentRequest;
|
||||
|
@ -231,7 +231,7 @@ void IntroPhone::phoneCheckDone(const MTPauth_CheckedPhone &result) {
|
||||
|
||||
checkRequest.start(1000);
|
||||
|
||||
sentRequest = MTP::send(MTPauth_SendCode(MTP_string(sentPhone), MTP_int(0), MTP_int(ApiId), MTP_string(ApiHash), MTP_string(Application::language())), rpcDone(&IntroPhone::phoneSubmitDone), rpcFail(&IntroPhone::phoneSubmitFail));
|
||||
sentRequest = MTP::send(MTPauth_SendCode(MTP_string(sentPhone), MTP_int(5), MTP_int(ApiId), MTP_string(ApiHash), MTP_string(Application::language())), rpcDone(&IntroPhone::phoneSubmitDone), rpcFail(&IntroPhone::phoneSubmitFail));
|
||||
} else {
|
||||
showError(lang(lng_bad_phone_noreg), true);
|
||||
enableAll(true);
|
||||
@ -250,6 +250,7 @@ void IntroPhone::phoneSubmitDone(const MTPauth_SentCode &result) {
|
||||
const MTPDauth_sentAppCode &d(result.c_auth_sentAppCode());
|
||||
intro()->setPhone(sentPhone, d.vphone_code_hash.c_string().v.c_str(), d.vphone_registered.v);
|
||||
intro()->setCallTimeout(d.vsend_call_timeout.v);
|
||||
intro()->setCodeByTelegram(true);
|
||||
}
|
||||
intro()->onIntroNext();
|
||||
}
|
||||
|
@ -78,7 +78,13 @@ LangString langCounted(ushort key0, ushort tag, float64 value);
|
||||
const char *langKeyName(LangKey key);
|
||||
|
||||
inline LangString langDayOfMonth(const QDate &date) {
|
||||
int32 month = date.month(), day = date.day();
|
||||
QDate c(QDate::currentDate());
|
||||
int32 month = date.month(), day = date.day(), year = date.year(), cyear = c.year(), cmonth = c.month();
|
||||
if (year != cyear) {
|
||||
if (year > cyear + 1 || cyear > year + 1 || (year == cyear + 1 && month + 12 > cmonth + 3) || (cyear == year + 1 && cmonth + 12 > month + 3)) {
|
||||
return (month > 0 && month <= 12) ? lng_month_day_year(lt_month, lang(LangKey(lng_month1 + month - 1)), lt_day, QString::number(day), lt_year, QString::number(year)) : qsl("MONTH_ERR");
|
||||
}
|
||||
}
|
||||
return (month > 0 && month <= 12) ? lng_month_day(lt_month, lang(LangKey(lng_month1 + month - 1)), lt_day, QString::number(day)) : qsl("MONTH_ERR");
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "Sonntag";
|
||||
|
||||
"lng_month_day" = "{day}. {month}";
|
||||
"lng_month_day_year" = "{day} {month}, {year}";
|
||||
|
||||
"lng_cancel" = "Abbrechen";
|
||||
"lng_continue" = "Weiter";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "Dein Code";
|
||||
"lng_code_desc" = "Wir haben dir einen Aktivierungscode gesendet.\nBitte Code hier eingeben.";
|
||||
"lng_code_telegram" = "Bitte den Code eingeben, den du in der\nzuvor benutzen [b]Telegram[/b]-App erhalten hast.";
|
||||
"lng_code_no_telegram" = "Code per SMS senden";
|
||||
"lng_code_call" = "Telegram ruft dich an in {minutes}:{seconds}";
|
||||
"lng_code_calling" = "Telegram ruft dich an..";
|
||||
"lng_code_called" = "Telegram ruft dich gerade an.";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Nachrichtenvorschau anzeigen";
|
||||
"lng_settings_use_windows" = "Windows Benachrichtigungen";
|
||||
"lng_settings_sound_notify" = "Ton abspielen";
|
||||
"lng_settings_include_muted" = "Stummgeschaltete Chats mitzählen";
|
||||
|
||||
"lng_notification_preview" = "Du hast eine neue Nachricht";
|
||||
|
||||
@ -386,6 +390,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Dateiübersicht";
|
||||
"lng_profile_audios" = "{count:_not_used_|# Sprachnachricht|# Sprachnachrichten} »";
|
||||
"lng_profile_audios_header" = "Übersicht Sprachnachrichten";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# Link|# Links} »";
|
||||
"lng_profile_shared_links_header" = "Linkübersicht";
|
||||
"lng_profile_audio_files_header" = "Wiedergabeliste";
|
||||
"lng_profile_show_all_types" = "Alle Filter anzeigen";
|
||||
"lng_profile_copy_phone" = "Telefonnummer kopieren";
|
||||
@ -443,6 +449,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "Videos";
|
||||
"lng_media_type_files" = "Dateien";
|
||||
"lng_media_type_audios" = "Sprachnachrichten";
|
||||
"lng_media_type_links" = "Links";
|
||||
|
||||
"lng_media_open_with" = "Öffnen mit";
|
||||
"lng_media_download" = "Download";
|
||||
@ -641,7 +648,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop wurde aktualisiert auf Version {version}\n\n{changes}\n\nGesamter Versionsverlauf:\n{link}";
|
||||
"lng_new_version_minor" = "— Fehlerbehebungen und Softwareoptimierungen";
|
||||
"lng_new_version_text" = "— Blockiere Nutzer über die Profilseite (im Chat auf den Namen oben tippen)\n— Windows 8, 8.1 und 10: Native Windowsbenachrichtigungen\n— Fehlerbehebung: Eingabemethoden unter Linux (Fcitx und iBus)";
|
||||
"lng_new_version_text" = "— Stummgeschaltete Chats können ab sofort optional mitgezählt werden (Einstellungen > Stummgeschaltete Chats mitzählen)\n— Übersicht der im Chat geteilten Links im Bereich 'Geteilte Medien'\n— GIF-Vorschau und PDF-Vorschau von Direktlinks (.pdf und .gif)";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-Steuerzeichen einfügen";
|
||||
|
||||
|
@ -60,6 +60,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "domingo";
|
||||
|
||||
"lng_month_day" = "{day} de {month}";
|
||||
"lng_month_day_year" = "{day} de {month} de {year}";
|
||||
|
||||
"lng_cancel" = "Cancelar";
|
||||
"lng_continue" = "Continuar";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "Tu código";
|
||||
"lng_code_desc" = "Hemos enviado un mensaje con un código de \nactivación a tu teléfono. Por favor, ponlo abajo.";
|
||||
"lng_code_telegram" = "Por favor, pon el código que acabas\nde recibir en tu otra aplicación de [b]Telegram[/b].";
|
||||
"lng_code_no_telegram" = "Enviar el código vía SMS";
|
||||
"lng_code_call" = "Telegram marcará tu número en {minutes}:{seconds}";
|
||||
"lng_code_calling" = "Solicitando una llamada de Telegram...";
|
||||
"lng_code_called" = "Telegram marcó tu número";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Mostrar la vista previa del mensaje";
|
||||
"lng_settings_use_windows" = "Usar notificaciones de Windows";
|
||||
"lng_settings_sound_notify" = "Reproducir sonido";
|
||||
"lng_settings_include_muted" = "Incluir los chats silenciados en el conteo de 'no leídos'";
|
||||
|
||||
"lng_notification_preview" = "Tienes un nuevo mensaje";
|
||||
|
||||
@ -386,6 +390,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Archivos";
|
||||
"lng_profile_audios" = "{count:_not_used_|# mensaje de voz|# mensajes de voz} »";
|
||||
"lng_profile_audios_header" = "Mensajes de voz";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# enlace|# enlaces} »";
|
||||
"lng_profile_shared_links_header" = "Enlaces";
|
||||
"lng_profile_audio_files_header" = "Lista de reproducción";
|
||||
"lng_profile_show_all_types" = "Mostrar todos los tipos";
|
||||
"lng_profile_copy_phone" = "Copiar número";
|
||||
@ -443,6 +449,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "Vídeos";
|
||||
"lng_media_type_files" = "Archivos";
|
||||
"lng_media_type_audios" = "Mensajes de voz";
|
||||
"lng_media_type_links" = "Enlaces";
|
||||
|
||||
"lng_media_open_with" = "Abrir con";
|
||||
"lng_media_download" = "Descargar";
|
||||
@ -641,7 +648,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop fue actualizada a la versión {version}\n\n{changes}\n\nEl historial completo está disponible aquí:\n{link}";
|
||||
"lng_new_version_minor" = "— Corrección de errores y otras mejoras menores";
|
||||
"lng_new_version_text" = "— Bloquea usuarios desde sus perfiles\n— Añadido el soporte para notificaciones Windows toast\n— Arreglados los métodos de entrada en Linux (Fcitx e IBus)";
|
||||
"lng_new_version_text" = "— Incluye los chats silenciados en el conteo de 'no leídos', en Ajustes\n— Vista y búsqueda de los enlaces compartidos, en 'Todos los archivos'\n— Vista previa al enviar enlaces a GIF animados o archivos PDF";
|
||||
|
||||
"lng_menu_insert_unicode" = "Insertar caracteres de control Unicode";
|
||||
|
||||
|
@ -60,12 +60,13 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "Domenica";
|
||||
|
||||
"lng_month_day" = "{day} {month}";
|
||||
"lng_month_day_year" = "{day} {month} {year}";
|
||||
|
||||
"lng_cancel" = "Annulla";
|
||||
"lng_continue" = "Continua";
|
||||
"lng_close" = "Chiudi";
|
||||
"lng_connecting" = "Connessione...";
|
||||
"lng_reconnecting" = "Riconnessione {count:ora|in # s|in # s}...";
|
||||
"lng_connecting" = "Connetto...";
|
||||
"lng_reconnecting" = "Riconnetto {count:ora|in # s|in # s}...";
|
||||
"lng_reconnecting_try_now" = "Prova ora";
|
||||
|
||||
"lng_status_service_notifications" = "notifiche di servizio";
|
||||
@ -86,7 +87,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_status_lastseen_date" = "ultimo accesso {date}";
|
||||
"lng_status_lastseen_date_time" = "ultimo accesso {date} alle {time}";
|
||||
"lng_status_online" = "in linea";
|
||||
"lng_status_connecting" = "connessione...";
|
||||
"lng_status_connecting" = "connetto...";
|
||||
|
||||
"lng_chat_status_unaccessible" = "gruppo non accessibile";
|
||||
"lng_chat_status_members" = "{count:nessun membro|# membro|# membri}";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "Codice";
|
||||
"lng_code_desc" = "Abbiamo inviato un messaggio col codice\ndi attivazione al tuo telefono. Inseriscilo qui";
|
||||
"lng_code_telegram" = "Per favore inserisci il codice che hai\nappena ricevuto nell'altra app di [b]Telegram[/b].";
|
||||
"lng_code_no_telegram" = "Invia codice tramite SMS";
|
||||
"lng_code_call" = "Telegram ti chiamerà tra {minutes}:{seconds}";
|
||||
"lng_code_calling" = "Richiedendo una telefonata da Telegram..";
|
||||
"lng_code_called" = "Telegram ti ha chiamato";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Mostra anteprima messaggio";
|
||||
"lng_settings_use_windows" = "Usa le notifiche di Windows";
|
||||
"lng_settings_sound_notify" = "Riproduci suono";
|
||||
"lng_settings_include_muted" = "Includi chat silenziate nel badge";
|
||||
|
||||
"lng_notification_preview" = "Hai un nuovo messaggio";
|
||||
|
||||
@ -198,7 +202,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_auto_update" = "Aggiorna automaticamente";
|
||||
"lng_settings_current_version" = "Versione {version}";
|
||||
"lng_settings_check_now" = "Cerca aggiornamenti";
|
||||
"lng_settings_update_checking" = "Ricerca aggiornamenti..";
|
||||
"lng_settings_update_checking" = "Cerco aggiornamenti..";
|
||||
"lng_settings_latest_installed" = "L'ultima versione è installata";
|
||||
"lng_settings_downloading" = "Download aggiornamento {ready} / {total} MB..";
|
||||
"lng_settings_update_ready" = "La nuova versione è pronta";
|
||||
@ -234,7 +238,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_download_path_clear" = "Elimina tutto";
|
||||
"lng_download_path_header" = "Scegli il percorso di download";
|
||||
"lng_download_path_default_radio" = "Cartella Telegram in «Download»";
|
||||
"lng_download_path_temp_radio" = "Cartella temporanea, pulita alla disconnessione";
|
||||
"lng_download_path_temp_radio" = "Cartella temporanea, pulita quando ti disconnetti";
|
||||
"lng_download_path_dir_radio" = "Cartella personalizzata, pulita manualmente";
|
||||
"lng_download_path_choose" = "Scegli il percorso di download";
|
||||
"lng_sure_clear_downloads" = "Vuoi eliminare tutti i file scaricati nella cartella temporanea? Sarà fatto automaticamente alla disconnessione o alla disinstallazione del programma";
|
||||
@ -305,9 +309,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_cloud_password_is_same" = "La password non è stata cambiata";
|
||||
|
||||
"lng_connection_type" = "Tipo di connessione:";
|
||||
"lng_connection_auto_connecting" = "Default (connessione..)";
|
||||
"lng_connection_auto_connecting" = "Default (connetto..)";
|
||||
"lng_connection_auto" = "Predefinito ({transport} in uso)";
|
||||
"lng_connection_proxy_connecting" = "Connessione tramite proxy..";
|
||||
"lng_connection_proxy_connecting" = "Connetto tramite proxy..";
|
||||
"lng_connection_proxy" = "{transport} con proxy";
|
||||
"lng_connection_header" = "Tipo di connessione";
|
||||
"lng_connection_auto_rb" = "Auto (TCP se disponibile o HTTP)";
|
||||
@ -386,6 +390,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Panoramica file";
|
||||
"lng_profile_audios" = "{count:_not_used_|# nota vocale|# note vocali} »";
|
||||
"lng_profile_audios_header" = "Panoramica note vocali";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# link condiviso|# link condivisi} »";
|
||||
"lng_profile_shared_links_header" = "Panoramica link condivisi";
|
||||
"lng_profile_audio_files_header" = "Playlist";
|
||||
"lng_profile_show_all_types" = "Mostra tutti i tipi";
|
||||
"lng_profile_copy_phone" = "Copia numero di telefono";
|
||||
@ -397,7 +403,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_create_group_title" = "Nuovo gruppo";
|
||||
|
||||
"lng_failed_add_participant" = "Impossibile aggiungere l'utente. Riprova più tardi.";
|
||||
"lng_failed_add_not_mutual" = "Se una persona lascia un gruppo,\nsolo un contatto in comune può reinvitarla\n(lei deve avere il tuo numero\ndi telefono, e tu il suo).";
|
||||
"lng_failed_add_not_mutual" = "Se una persona lascia un gruppo, solo\nun contatto in comune può reinvitarla\n(chi ti invita deve avere il tuo\ncontatto su Telegram, e viceversa).";
|
||||
|
||||
"lng_sure_delete_contact" = "Sicuro di volere eliminare {contact} dalla tua lista dei contatti?";
|
||||
"lng_sure_delete_history" = "Sicuro di voler eliminare tutta la cronologia dei messaggi con {contact}?\n\nQuesta azione non può essere annullata.";
|
||||
@ -443,6 +449,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "Video";
|
||||
"lng_media_type_files" = "File";
|
||||
"lng_media_type_audios" = "Note vocali";
|
||||
"lng_media_type_links" = "Link condivisi";
|
||||
|
||||
"lng_media_open_with" = "Apri con";
|
||||
"lng_media_download" = "Download";
|
||||
@ -639,9 +646,9 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_authorization" = "{name},\nAbbiamo rilevato un accesso al tuo account da un nuovo dispositivo il {day}, {date} alle {time}\n\nDispositivo: {device}\nPosizione: {location}\n\nSe non sei tu, puoi andare su Impostazioni – Mostra tutte le sessioni e terminare quella sessione.\n\nSe credi che qualcuno si sia collegato al tuo account contro il tuo volere, puoi attivare la verifica in due passaggi nelle Impostazioni. \n\nGrazie, \nIl Team di Telegram";
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli update è disponibile qui:\n{link}";
|
||||
"lng_new_version_wrap" = "Telegram Desktop si è aggiornato alla versione {version}\n\n{changes}\n\nLa cronologia degli aggiornamenti è disponibile qui:\n{link}";
|
||||
"lng_new_version_minor" = "— Bug fix e altri miglioramenti minori";
|
||||
"lng_new_version_text" = "— Blocca gli utenti dalla loro pagina profilo\n— Aggiunto il supporto per le notifiche toast di Windows\n— Risolti i problemi con alcuni metodi di input su Linux (Fcitx and IBus)";
|
||||
"lng_new_version_text" = "— Includi chat silenziate nel badge nelle Impostazioni\n— Panoramica dei link condivisi e ricerca nei media condivisi\n— Anteprima quando invii una GIF o un file PDF.";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserisci carattere di controllo Unicode";
|
||||
|
||||
|
@ -60,6 +60,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "일요일";
|
||||
|
||||
"lng_month_day" = "{month} {day}일";
|
||||
"lng_month_day_year" = "{month} {day}, {year}";
|
||||
|
||||
"lng_cancel" = "취소";
|
||||
"lng_continue" = "계속";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "코드번호";
|
||||
"lng_code_desc" = "인증코드 메세지를 휴대폰으로 전송하였습니다.\n인증코드를 아래에 입력하여 주세요.";
|
||||
"lng_code_telegram" = "[b]텔레그램[/b] 앱으로 부터 방금 수신받은,\n코드를 입력해주세요.";
|
||||
"lng_code_no_telegram" = "코드를 SMS로 전송";
|
||||
"lng_code_call" = "텔레그램이 {minutes}:{seconds}후에는 전화를 겁니다.";
|
||||
"lng_code_calling" = "텔레그램으로부터 전화 요청을 하고 있습니다..";
|
||||
"lng_code_called" = "텔레그램이 회원님의 전화번호로 전화를 걸었습니다.";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "메시지 미리보기";
|
||||
"lng_settings_use_windows" = "윈도우 알림 사용";
|
||||
"lng_settings_sound_notify" = "소리 재생";
|
||||
"lng_settings_include_muted" = "안 읽은 메시지에 음소거된 채팅방 포함";
|
||||
|
||||
"lng_notification_preview" = "새로운 메시지가 있습니다.";
|
||||
|
||||
@ -386,6 +390,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "파일 내역";
|
||||
"lng_profile_audios" = "{count:_not_used_|#개의 음성 메시지|#개의 음성 메시지} »";
|
||||
"lng_profile_audios_header" = "음성 메시지 내역";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# 공유된 링크|# 공유된 링크} »";
|
||||
"lng_profile_shared_links_header" = "공유된 링크 현황";
|
||||
"lng_profile_audio_files_header" = "재생목록";
|
||||
"lng_profile_show_all_types" = "모든 유형 보기";
|
||||
"lng_profile_copy_phone" = "전화번호 복사";
|
||||
@ -443,6 +449,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "비디오 파일";
|
||||
"lng_media_type_files" = "파일";
|
||||
"lng_media_type_audios" = "음성 메시지";
|
||||
"lng_media_type_links" = "공유된 링크";
|
||||
|
||||
"lng_media_open_with" = "다음으로 열기";
|
||||
"lng_media_download" = "다운로드";
|
||||
@ -641,7 +648,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "텔레그램 데스크탑은 {version} 버전으로 업데이트 되었습니다.\n\n{changes}\n\n전체 버전 히스토리는 아래에서 확인 가능합니다:\n{link}";
|
||||
"lng_new_version_minor" = "— 버그 수정 및 일부 기능 향상";
|
||||
"lng_new_version_text" = "— 프로필 화면에서 사용자 차단\n— 윈도우 알림 지원\n— 리눅스 입력 방법 수정 (Fcitx and IBus)";
|
||||
"lng_new_version_text" = "— 설정에서 안 읽은 메시지 수에 음소거된 채팅방 포함\n— 공유된 링크 현황과 공유된 미디어 검색 기능\n— GIF 링크 및 PDF 파일 전송시 프리뷰 기능";
|
||||
|
||||
"lng_menu_insert_unicode" = "유니코드 문자를 입력하세요.";
|
||||
|
||||
|
@ -60,6 +60,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "zondag";
|
||||
|
||||
"lng_month_day" = "{day} {month}";
|
||||
"lng_month_day_year" = "{day} {month}, {year}";
|
||||
|
||||
"lng_cancel" = "Annuleren";
|
||||
"lng_continue" = "Doorgaan";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "Je code";
|
||||
"lng_code_desc" = "We hebben een bericht met activatiecode\nverstuurd naar je nummer, geef deze hieronder in.";
|
||||
"lng_code_telegram" = "Voer de code in die je zojuist\nhebt ontvangen in je vorige [b]Telegram[/b]-app.";
|
||||
"lng_code_no_telegram" = "Verstuur code via SMS";
|
||||
"lng_code_call" = "Telegram belt je over {minutes}:{seconds}";
|
||||
"lng_code_calling" = "Oproepverzoek versturen naar Telegram";
|
||||
"lng_code_called" = "Telegram heeft je nummer gebeld";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Voorvertoning weergeven";
|
||||
"lng_settings_use_windows" = "Windows-berichtgeving gebruiken";
|
||||
"lng_settings_sound_notify" = "Geluiden afspelen";
|
||||
"lng_settings_include_muted" = "Stille chats meetellen in ongelezen";
|
||||
|
||||
"lng_notification_preview" = "Je hebt een nieuw bericht";
|
||||
|
||||
@ -386,6 +390,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_files_header" = "Bestandsoverzicht";
|
||||
"lng_profile_audios" = "{count:_not_used_|# spraakbericht|# spraakberichten} »";
|
||||
"lng_profile_audios_header" = "Overzicht van spraakberichten";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# gedeelde link|# gedeelde links} »";
|
||||
"lng_profile_shared_links_header" = "Overzicht van gedeelde links";
|
||||
"lng_profile_audio_files_header" = "Afspeellijst";
|
||||
"lng_profile_show_all_types" = "Alles weergeven";
|
||||
"lng_profile_copy_phone" = "Telefoonnummer kopiëren";
|
||||
@ -443,6 +449,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_media_type_videos" = "Video's";
|
||||
"lng_media_type_files" = "Bestanden";
|
||||
"lng_media_type_audios" = "Spraakberichten";
|
||||
"lng_media_type_links" = "Gedeelde links";
|
||||
|
||||
"lng_media_open_with" = "Openen met";
|
||||
"lng_media_download" = "Downloaden";
|
||||
@ -641,7 +648,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram is bijgewerkt naar versie {version}\n\n{changes} \n\nVolledige versiegeschiedenis is hier te vinden:\n{link}";
|
||||
"lng_new_version_minor" = "— Probleemoplossing en andere kleine verbeteringen";
|
||||
"lng_new_version_text" = "— Blokkeer gebruikers vanaf de profielpagina\n— Ondersteuning voor Windows toast-meldingen\n— Problemen met invoermethodes onder Linux (Fcitx and IBus) opgelost";
|
||||
"lng_new_version_text" = "— Stille chats meetellen in ongelezen teller via instellingen\n— Gedeelde links-overzicht en zoeken in gedeelde media\n— Voorvertoning voor links naar GIF-animaties en PDF-bestanden";
|
||||
|
||||
"lng_menu_insert_unicode" = "Unicode-besturingsteken invoegen";
|
||||
|
||||
|
@ -60,6 +60,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_weekday7_full" = "Domingo";
|
||||
|
||||
"lng_month_day" = "{month} {day}";
|
||||
"lng_month_day_year" = "{day} {month}, {year}";
|
||||
|
||||
"lng_cancel" = "Cancelar";
|
||||
"lng_continue" = "Continuar";
|
||||
@ -117,6 +118,8 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_code_ph" = "Código";
|
||||
"lng_code_desc" = "Enviamos uma SMS com um código de ativação\npara o seu telefone. Insira-o abaixo.";
|
||||
"lng_code_telegram" = "Por favor insira código recebido\nem seu aplicativo prévio do [b]Telegram[/b]";
|
||||
"lng_code_no_telegram" = "Enviar código via SMS";
|
||||
"lng_code_call" = "Telegram irá te ligar em {minutes}{seconds}";
|
||||
"lng_code_calling" = "Aguardando a ligação do Telegram..";
|
||||
"lng_code_called" = "Telegram ligou para o seu número";
|
||||
@ -188,6 +191,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_settings_show_preview" = "Mostrar pré-visualização da mensagem";
|
||||
"lng_settings_use_windows" = "Usar notificações do Windows";
|
||||
"lng_settings_sound_notify" = "Tocar som";
|
||||
"lng_settings_include_muted" = "Incluir chats silenciados no contador de notificações";
|
||||
|
||||
"lng_notification_preview" = "Você tem uma nova mensagem";
|
||||
|
||||
@ -380,12 +384,14 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
"lng_profile_no_media" = "Nenhuma mídia nessa conversa.";
|
||||
"lng_profile_photos" = "{count:_not_used_|# foto|# fotos} »";
|
||||
"lng_profile_photos_header" = "Fotos";
|
||||
"lng_profile_videos" = "{count:_not_used_|# arquivo de vídeo|# arquivo de vídeos} »";
|
||||
"lng_profile_videos" = "{count:_not_used_|# vídeo|# vídeos} »";
|
||||
"lng_profile_videos_header" = "Vídeos";
|
||||
"lng_profile_files" = "{count:_not_used_|# arquivo|# arquivos} »";
|
||||
"lng_profile_files_header" = "Arquivos";
|
||||
"lng_profile_audios" = "{count:_not_used_|# mensagem de voz|# mensagens de voz} »";
|
||||
"lng_profile_audios_header" = "Mensagens de voz";
|
||||
"lng_profile_shared_links" = "{count:_not_used_|# link|# links} »";
|
||||
"lng_profile_shared_links_header" = "Links";
|
||||
"lng_profile_audio_files_header" = "Reprodução";
|
||||
"lng_profile_show_all_types" = "Mostrar todos os tipos";
|
||||
"lng_profile_copy_phone" = "Copiar número de telefone";
|
||||
@ -440,14 +446,15 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_media_type" = "Tipo de mídia";
|
||||
"lng_media_type_photos" = "Fotos";
|
||||
"lng_media_type_videos" = "Arquivos de vídeo";
|
||||
"lng_media_type_videos" = "Vídeos";
|
||||
"lng_media_type_files" = "Arquivos";
|
||||
"lng_media_type_audios" = "Mensagens de voz";
|
||||
"lng_media_type_links" = "Links";
|
||||
|
||||
"lng_media_open_with" = "Abrir Com";
|
||||
"lng_media_download" = "Download";
|
||||
"lng_media_cancel" = "Cancelar";
|
||||
"lng_media_video" = "Arquivo de vídeo";
|
||||
"lng_media_video" = "Vídeos";
|
||||
"lng_media_audio" = "Mensagem de voz";
|
||||
|
||||
"lng_emoji_category0" = "Frequentemente usado";
|
||||
@ -641,7 +648,7 @@ Copyright (c) 2014 John Preston, https://desktop.telegram.org
|
||||
|
||||
"lng_new_version_wrap" = "Telegram Desktop foi atualizado para a versão {version}\n\n{changes}\n\nHistórico completo de mudanças disponível aqui:\n{link}";
|
||||
"lng_new_version_minor" = "— Resolução de bugs e outras menores melhorias";
|
||||
"lng_new_version_text" = "— Bloqueie usuários direto da página do perfil\n— Adicionado suporte às notificações de sistema do Windows\n— Consertado métodos de entrada no Linux (Fcitx e IBus)";
|
||||
"lng_new_version_text" = "— Incluir chats silenciados no contador de notificações em Configurações\n— Visão geral dos links compartilhados e busca nas mídias compartilhadas\n— Pré-visualização em links com GIF e arquivos em PDF";
|
||||
|
||||
"lng_menu_insert_unicode" = "Inserir caractere de controle Unicode";
|
||||
|
||||
|
@ -730,6 +730,14 @@ namespace {
|
||||
cSetSoundNotify(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiIncludeMuted: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetIncludeMuted(v == 1);
|
||||
} break;
|
||||
|
||||
case dbiDesktopNotify: {
|
||||
qint32 v;
|
||||
stream >> v;
|
||||
@ -744,7 +752,9 @@ namespace {
|
||||
if (!_checkStreamStatus(stream)) return false;
|
||||
|
||||
cSetWindowsNotifications(v == 1);
|
||||
cSetCustomNotifies((App::wnd() ? App::wnd()->psHasNativeNotifications() : true) && !cWindowsNotifications());
|
||||
if (cPlatform() == dbipWindows) {
|
||||
cSetCustomNotifies((App::wnd() ? !App::wnd()->psHasNativeNotifications() : true) || !cWindowsNotifications());
|
||||
}
|
||||
} break;
|
||||
|
||||
case dbiWorkMode: {
|
||||
@ -1279,7 +1289,7 @@ namespace {
|
||||
_writeMap(WriteMapFast);
|
||||
}
|
||||
|
||||
uint32 size = 13 * (sizeof(quint32) + sizeof(qint32));
|
||||
uint32 size = 14 * (sizeof(quint32) + sizeof(qint32));
|
||||
size += sizeof(quint32) + _stringSize(cAskDownloadPath() ? QString() : cDownloadPath());
|
||||
size += sizeof(quint32) + sizeof(qint32) + (cRecentEmojisPreload().isEmpty() ? cGetRecentEmojis().size() : cRecentEmojisPreload().size()) * (sizeof(uint64) + sizeof(ushort));
|
||||
size += sizeof(quint32) + sizeof(qint32) + cEmojiVariants().size() * (sizeof(uint32) + sizeof(uint64));
|
||||
@ -1293,6 +1303,7 @@ namespace {
|
||||
data.stream << quint32(dbiReplaceEmojis) << qint32(cReplaceEmojis() ? 1 : 0);
|
||||
data.stream << quint32(dbiDefaultAttach) << qint32(cDefaultAttach());
|
||||
data.stream << quint32(dbiSoundNotify) << qint32(cSoundNotify());
|
||||
data.stream << quint32(dbiIncludeMuted) << qint32(cIncludeMuted());
|
||||
data.stream << quint32(dbiDesktopNotify) << qint32(cDesktopNotify());
|
||||
data.stream << quint32(dbiNotifyView) << qint32(cNotifyView());
|
||||
data.stream << quint32(dbiWindowsNotifications) << qint32(cWindowsNotifications());
|
||||
|
@ -81,6 +81,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
DEBUG_LOG(("Application Info: Telegram done, result: %1").arg(result));
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
if (cRestartingUpdate()) {
|
||||
if (DevVersion) {
|
||||
LOG(("Writing 'devversion' file before launching the Updater!"));
|
||||
@ -93,7 +94,9 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
DEBUG_LOG(("Application Info: executing updater to install update.."));
|
||||
psExecUpdater();
|
||||
} else if (cRestarting()) {
|
||||
} else
|
||||
#endif
|
||||
if (cRestarting()) {
|
||||
DEBUG_LOG(("Application Info: executing Telegram, because of restart.."));
|
||||
psExecTelegram();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ void TopBarWidget::onInfoClicked() {
|
||||
void TopBarWidget::onAddContact() {
|
||||
PeerData *p = App::main() ? App::main()->profilePeer() : 0;
|
||||
UserData *u = (p && !p->chat) ? p->asUser() : 0;
|
||||
if (u) App::wnd()->showLayer(new AddContactBox(u->firstName, u->lastName, u->phone));
|
||||
if (u) App::wnd()->showLayer(new AddContactBox(u->firstName, u->lastName, u->phone.isEmpty() ? App::phoneFromSharedContact(App::userFromPeer(u->id)) : u->phone));
|
||||
}
|
||||
|
||||
void TopBarWidget::onEdit() {
|
||||
@ -278,7 +278,7 @@ void TopBarWidget::showAll() {
|
||||
return;
|
||||
}
|
||||
PeerData *p = App::main() ? App::main()->profilePeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0;
|
||||
if (p && (p->chat || p->asUser()->contact >= 0)) {
|
||||
if (p && (p->chat || p->asUser()->contact >= 0 || !App::phoneFromSharedContact(App::userFromPeer(p->id)).isEmpty())) {
|
||||
if (p->chat) {
|
||||
if (p->asChat()->forbidden) {
|
||||
_edit.hide();
|
||||
@ -982,6 +982,62 @@ DialogsIndexed &MainWidget::dialogsList() {
|
||||
return dialogs.dialogsList();
|
||||
}
|
||||
|
||||
inline bool replaceCharBySpace(ushort code) {
|
||||
// \xe2\x80[\xa8 - \xac\xad] // 8232 - 8237
|
||||
// QString from1 = QString::fromUtf8("\xe2\x80\xa8"), to1 = QString::fromUtf8("\xe2\x80\xad");
|
||||
// \xcc[\xb3\xbf\x8a] // 819, 831, 778
|
||||
// QString bad1 = QString::fromUtf8("\xcc\xb3"), bad2 = QString::fromUtf8("\xcc\xbf"), bad3 = QString::fromUtf8("\xcc\x8a");
|
||||
// [\x00\x01\x02\x07\x08\x0b-\x1f] // '\t' = 0x09
|
||||
return (code >= 0x00 && code <= 0x02) || (code >= 0x07 && code <= 0x09) || (code >= 0x0b && code <= 0x1f) ||
|
||||
(code == 819) || (code == 831) || (code == 778) || (code >= 8232 && code <= 8237);
|
||||
}
|
||||
|
||||
QString cleanMessage(const QString &text) {
|
||||
QString result = text;
|
||||
QChar *_start = result.data(), *_end = _start + result.size(), *start = _start, *end = _end, *ch = start, *copy = 0;
|
||||
for (; ch != end; ++ch) {
|
||||
if (ch->unicode() == '\r') {
|
||||
copy = ch + 1;
|
||||
break;
|
||||
} else if (replaceCharBySpace(ch->unicode())) {
|
||||
*ch = ' ';
|
||||
}
|
||||
}
|
||||
if (copy) {
|
||||
for (; copy != end; ++copy) {
|
||||
if (copy->unicode() == '\r') {
|
||||
continue;
|
||||
} else if (replaceCharBySpace(copy->unicode())) {
|
||||
*ch++ = ' ';
|
||||
} else {
|
||||
*ch++ = *copy;
|
||||
}
|
||||
}
|
||||
end = ch;
|
||||
}
|
||||
|
||||
// PHP trim() removes [ \t\n\r\x00\x0b], we have removed [\t\r\x00\x0b] before, so
|
||||
for (; start != end; ++start) {
|
||||
if (start->unicode() != ' ' && start->unicode() != '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (QChar *e = end - 1; start != end; end = e) {
|
||||
if (e->unicode() != ' ' && e->unicode() != '\n') {
|
||||
break;
|
||||
}
|
||||
--e;
|
||||
}
|
||||
if (start == end) {
|
||||
return QString();
|
||||
} else if (start > _start) {
|
||||
return QString(start, end - start);
|
||||
} else if (end < _end) {
|
||||
result.resize(end - start);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId replyTo, WebPageId webPageId) {
|
||||
saveRecentHashtags(text);
|
||||
QString sendingText, leftText = text;
|
||||
@ -990,10 +1046,13 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
|
||||
MsgId newId = clientMsgId();
|
||||
uint64 randomId = MTP::nonce<uint64>();
|
||||
|
||||
sendingText = cleanMessage(sendingText);
|
||||
|
||||
App::historyRegRandom(randomId, newId);
|
||||
App::historyRegSentText(randomId, sendingText);
|
||||
|
||||
MTPstring msgText(MTP_string(sendingText));
|
||||
int32 flags = newMessageFlags(hist->peer); // unread, out
|
||||
int32 flags = newMessageFlags(hist->peer) | MTPDmessage::flag_entities; // unread, out
|
||||
int32 sendFlags = 0;
|
||||
if (replyTo) {
|
||||
flags |= MTPDmessage::flag_reply_to_msg_id;
|
||||
@ -1005,9 +1064,11 @@ void MainWidget::sendPreparedText(History *hist, const QString &text, MsgId repl
|
||||
} else if (webPageId) {
|
||||
WebPageData *page = App::webPage(webPageId);
|
||||
media = MTP_messageMediaWebPage(MTP_webPagePending(MTP_long(page->id), MTP_int(page->pendingTill)));
|
||||
flags |= MTPDmessage::flag_media;
|
||||
}
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, MTPnullEntities));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, MTPnullEntities), App::main()->rpcDone(&MainWidget::sentDataReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
MTPVector<MTPMessageEntity> localEntities = linksToMTP(textParseLinks(sendingText, itemTextParseOptions(hist, App::self()).flags));
|
||||
hist->addToBack(MTP_message(MTP_int(flags), MTP_int(newId), MTP_int(MTP::authedId()), App::peerToMTP(hist->peer->id), MTPint(), MTPint(), MTP_int(replyTo), MTP_int(unixtime()), msgText, media, MTPnullMarkup, localEntities));
|
||||
hist->sendRequestId = MTP::send(MTPmessages_SendMessage(MTP_int(sendFlags), hist->peer->input, MTP_int(replyTo), msgText, MTP_long(randomId), MTPnullMarkup, localEntities), App::main()->rpcDone(&MainWidget::sentUpdatesReceived, randomId), RPCFailHandlerPtr(), 0, 0, hist->sendRequestId);
|
||||
}
|
||||
|
||||
finishForwarding(hist);
|
||||
@ -1173,6 +1234,7 @@ void MainWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type) {
|
||||
case OverviewVideos: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaVideos, lang(lng_media_type_videos))), SIGNAL(clicked()), this, SLOT(onVideosSelect())); break;
|
||||
case OverviewDocuments: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaDocuments, lang(lng_media_type_files))), SIGNAL(clicked()), this, SLOT(onDocumentsSelect())); break;
|
||||
case OverviewAudios: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaAudios, lang(lng_media_type_audios))), SIGNAL(clicked()), this, SLOT(onAudiosSelect())); break;
|
||||
case OverviewLinks: connect(_mediaType.addButton(new IconedButton(this, st::dropdownMediaLinks, lang(lng_media_type_links))), SIGNAL(clicked()), this, SLOT(onLinksSelect())); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1193,6 +1255,9 @@ void MainWidget::itemRemoved(HistoryItem *item) {
|
||||
if (history.peer() == item->history()->peer) {
|
||||
history.itemRemoved(item);
|
||||
}
|
||||
if (overview && overview->peer() == item->history()->peer) {
|
||||
overview->itemRemoved(item);
|
||||
}
|
||||
itemRemovedGif(item);
|
||||
if (!_toForward.isEmpty()) {
|
||||
SelectedItemSet::iterator i = _toForward.find(item->id);
|
||||
@ -1730,11 +1795,12 @@ void MainWidget::dialogsCancelled() {
|
||||
}
|
||||
|
||||
void MainWidget::serviceNotification(const QString &msg, const MTPMessageMedia &media, bool unread) {
|
||||
int32 flags = unread ? MTPDmessage_flag_unread : 0;
|
||||
int32 flags = (unread ? MTPDmessage_flag_unread : 0) | MTPDmessage::flag_entities;
|
||||
QString sendingText, leftText = msg;
|
||||
HistoryItem *item = 0;
|
||||
while (textSplit(sendingText, leftText, MaxMessageSize)) {
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, MTPnullEntities), unread ? 1 : 2);
|
||||
MTPVector<MTPMessageEntity> localEntities = linksToMTP(textParseLinks(sendingText, _historyTextOptions.flags));
|
||||
item = App::histories().addToBack(MTP_message(MTP_int(flags), MTP_int(clientMsgId()), MTP_int(ServiceUserId), MTP_peerUser(MTP_int(MTP::authedId())), MTPint(), MTPint(), MTPint(), MTP_int(unixtime()), MTP_string(sendingText), media, MTPnullMarkup, localEntities), unread ? 1 : 2);
|
||||
}
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
@ -2217,51 +2283,8 @@ void MainWidget::windowShown() {
|
||||
history.windowShown();
|
||||
}
|
||||
|
||||
void MainWidget::sentDataReceived(uint64 randomId, const MTPmessages_SentMessage &result) {
|
||||
switch (result.type()) {
|
||||
case mtpc_messages_sentMessage: {
|
||||
const MTPDmessages_sentMessage &d(result.c_messages_sentMessage());
|
||||
|
||||
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
||||
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
HistoryItem *item = App::histItemById(d.vid.v);
|
||||
if (item) {
|
||||
item->setMedia(d.vmedia);
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_messages_sentMessageLink: {
|
||||
const MTPDmessages_sentMessageLink &d(result.c_messages_sentMessageLink());
|
||||
|
||||
if (randomId) feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
||||
|
||||
if (updInited) {
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsSentMessage.insert(ptsKey(SkippedSentMessage), result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
App::feedUserLinks(d.vlinks);
|
||||
|
||||
if (d.vmedia.type() != mtpc_messageMediaEmpty) {
|
||||
HistoryItem *item = App::histItemById(d.vid.v);
|
||||
if (item) {
|
||||
item->setMedia(d.vmedia);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
};
|
||||
}
|
||||
|
||||
void MainWidget::sentUpdatesReceived(const MTPUpdates &result) {
|
||||
handleUpdates(result);
|
||||
void MainWidget::sentUpdatesReceived(uint64 randomId, const MTPUpdates &result) {
|
||||
handleUpdates(result, randomId);
|
||||
App::emitPeerUpdated();
|
||||
}
|
||||
|
||||
@ -2506,6 +2529,11 @@ void MainWidget::onAudiosSelect() {
|
||||
_mediaType.hideStart();
|
||||
}
|
||||
|
||||
void MainWidget::onLinksSelect() {
|
||||
if (overview) overview->switchType(OverviewLinks);
|
||||
_mediaType.hideStart();
|
||||
}
|
||||
|
||||
TopBarWidget *MainWidget::topBar() {
|
||||
return &_topBar;
|
||||
}
|
||||
@ -2531,7 +2559,19 @@ void MainWidget::onPeerShown(PeerData *peer) {
|
||||
_topBar.hide();
|
||||
}
|
||||
resizeEvent(0);
|
||||
if (animating()) _topBar.hide();
|
||||
if (animating()) {
|
||||
_topBar.hide();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::searchInPeer(PeerData *peer) {
|
||||
dialogs.searchInPeer(peer);
|
||||
if (cWideMode()) {
|
||||
dialogs.activate();
|
||||
} else {
|
||||
dialogsToUp();
|
||||
showDialogs();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWidget::searchInPeer(PeerData *peer) {
|
||||
@ -2672,7 +2712,7 @@ void MainWidget::applySkippedPtsUpdates() {
|
||||
switch (i.value()) {
|
||||
case SkippedUpdate: feedUpdate(_byPtsUpdate.value(i.key())); break;
|
||||
case SkippedUpdates: handleUpdates(_byPtsUpdates.value(i.key())); break;
|
||||
case SkippedSentMessage: sentDataReceived(0, _byPtsSentMessage.value(i.key())); break;
|
||||
// case SkippedSentMessage: sentDataReceived(0, _byPtsSentMessage.value(i.key())); break;
|
||||
}
|
||||
}
|
||||
--updSkipPtsUpdateLevel;
|
||||
@ -2684,7 +2724,7 @@ void MainWidget::clearSkippedPtsUpdates() {
|
||||
_byPtsQueue.clear();
|
||||
_byPtsUpdate.clear();
|
||||
_byPtsUpdates.clear();
|
||||
_byPtsSentMessage.clear();
|
||||
// _byPtsSentMessage.clear();
|
||||
updSkipPtsUpdateLevel = 0;
|
||||
}
|
||||
|
||||
@ -2768,7 +2808,9 @@ void MainWidget::start(const MTPUser &user) {
|
||||
|
||||
cSetOtherOnline(0);
|
||||
App::feedUsers(MTP_vector<MTPUser>(1, user));
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
App::app()->startUpdateCheck();
|
||||
#endif
|
||||
MTP::send(MTPupdates_GetState(), rpcDone(&MainWidget::gotState));
|
||||
update();
|
||||
if (!cStartUrl().isEmpty()) {
|
||||
@ -2941,6 +2983,8 @@ void MainWidget::inviteImportDone(const MTPUpdates &updates) {
|
||||
} break;
|
||||
case mtpc_updateShortChatMessage: {
|
||||
} break;
|
||||
case mtpc_updateShortSentMessage: {
|
||||
} break;
|
||||
case mtpc_updatesTooLong: {
|
||||
} break;
|
||||
}
|
||||
@ -3035,7 +3079,6 @@ void MainWidget::gotNotifySetting(MTPInputNotifyPeer peer, const MTPPeerNotifySe
|
||||
case mtpc_inputNotifyAll: applyNotifySetting(MTP_notifyAll(), settings); break;
|
||||
case mtpc_inputNotifyUsers: applyNotifySetting(MTP_notifyUsers(), settings); break;
|
||||
case mtpc_inputNotifyChats: applyNotifySetting(MTP_notifyChats(), settings); break;
|
||||
case mtpc_inputNotifyGeoChatPeer: break; // no MTP_peerGeoChat
|
||||
case mtpc_inputNotifyPeer:
|
||||
switch (peer.c_inputNotifyPeer().vpeer.type()) {
|
||||
case mtpc_inputPeerEmpty: applyNotifySetting(MTP_notifyPeer(MTP_peerUser(MTP_int(0))), settings); break;
|
||||
@ -3294,7 +3337,7 @@ void MainWidget::updateReceived(const mtpPrime *from, const mtpPrime *end) {
|
||||
update();
|
||||
}
|
||||
|
||||
void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
void MainWidget::handleUpdates(const MTPUpdates &updates, uint64 randomId) {
|
||||
switch (updates.type()) {
|
||||
case mtpc_updates: {
|
||||
const MTPDupdates &d(updates.c_updates());
|
||||
@ -3349,7 +3392,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
return;
|
||||
}
|
||||
bool out = (d.vflags.v & MTPDmessage_flag_out);
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, MTPnullEntities));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, out ? MTP_int(MTP::authedId()) : d.vuser_id, MTP_peerUser(out ? d.vuser_id : MTP_int(MTP::authedId())), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
@ -3369,7 +3412,7 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, MTPnullEntities));
|
||||
HistoryItem *item = App::histories().addToBack(MTP_message(d.vflags, d.vid, d.vfrom_id, MTP_peerChat(d.vchat_id), d.vfwd_from_id, d.vfwd_date, d.vreply_to_msg_id, d.vdate, d.vmessage, MTP_messageMediaEmpty(), MTPnullMarkup, d.has_entities() ? d.ventities : MTPnullEntities));
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
}
|
||||
@ -3377,6 +3420,41 @@ void MainWidget::handleUpdates(const MTPUpdates &updates) {
|
||||
updSetState(0, d.vdate.v, updQts, updSeq);
|
||||
} break;
|
||||
|
||||
case mtpc_updateShortSentMessage: {
|
||||
const MTPDupdateShortSentMessage &d(updates.c_updateShortSentMessage());
|
||||
HistoryItem *item = 0;
|
||||
if (randomId) {
|
||||
QString text = App::histSentTextByItem(randomId);
|
||||
feedUpdate(MTP_updateMessageID(d.vid, MTP_long(randomId))); // ignore real date
|
||||
if (!text.isEmpty()) {
|
||||
bool hasLinks = d.has_entities() && !d.ventities.c_vector().v.isEmpty();
|
||||
item = App::histItemById(d.vid.v);
|
||||
if (item && ((hasLinks && !item->hasTextLinks()) || (!hasLinks && item->textHasLinks()))) {
|
||||
bool was = item->hasTextLinks();
|
||||
item->setText(text, d.has_entities() ? linksFromMTP(d.ventities.c_vector().v) : LinksInText());
|
||||
item->initDimensions(0);
|
||||
itemResized(item);
|
||||
if (!was && item->hasTextLinks()) {
|
||||
item->history()->addToOverview(item, OverviewLinks);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!updPtsUpdated(d.vpts.v, d.vpts_count.v)) {
|
||||
_byPtsUpdates.insert(ptsKey(SkippedUpdates), updates);
|
||||
return;
|
||||
}
|
||||
if (!item) {
|
||||
item = App::histItemById(d.vid.v);
|
||||
}
|
||||
if (item) {
|
||||
item->setMedia(d.has_media() ? (&d.vmedia) : 0);
|
||||
}
|
||||
|
||||
updSetState(0, d.vdate.v, updQts, updSeq);
|
||||
} break;
|
||||
|
||||
case mtpc_updatesTooLong: {
|
||||
MTP_LOG(0, ("getDifference { good - updatesTooLong received }%1").arg(cTestMode() ? " TESTMODE" : ""));
|
||||
return getDifference();
|
||||
@ -3394,6 +3472,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
_byPtsUpdate.insert(ptsKey(SkippedUpdate), update);
|
||||
return;
|
||||
}
|
||||
if (d.vmessage.type() == mtpc_message) { // index forwarded messages to links overview
|
||||
App::checkEntitiesUpdate(d.vmessage.c_message());
|
||||
}
|
||||
|
||||
HistoryItem *item = App::histories().addToBack(d.vmessage);
|
||||
if (item) {
|
||||
history.peerMessagesUpdated(item->history()->peer->id);
|
||||
@ -3434,6 +3516,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
App::historyUnregRandom(d.vrandom_id.v);
|
||||
}
|
||||
App::historyUnregSentText(d.vrandom_id.v);
|
||||
} break;
|
||||
|
||||
case mtpc_updateReadMessagesContents: {
|
||||
@ -3627,10 +3710,6 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewGeoChatMessage: {
|
||||
const MTPDupdateNewGeoChatMessage &d(update.c_updateNewGeoChatMessage());
|
||||
} break;
|
||||
|
||||
case mtpc_updateNewEncryptedMessage: {
|
||||
const MTPDupdateNewEncryptedMessage &d(update.c_updateNewEncryptedMessage());
|
||||
} break;
|
||||
|
@ -222,8 +222,10 @@ public:
|
||||
|
||||
void windowShown();
|
||||
|
||||
void sentDataReceived(uint64 randomId, const MTPmessages_SentMessage &data);
|
||||
void sentUpdatesReceived(const MTPUpdates &updates);
|
||||
void sentUpdatesReceived(uint64 randomId, const MTPUpdates &updates);
|
||||
void sentUpdatesReceived(const MTPUpdates &updates) {
|
||||
return sentUpdatesReceived(0, updates);
|
||||
}
|
||||
void msgUpdated(PeerId peer, const HistoryItem *msg);
|
||||
void historyToDown(History *hist);
|
||||
void dialogsToUp();
|
||||
@ -429,6 +431,7 @@ public slots:
|
||||
void onVideosSelect();
|
||||
void onDocumentsSelect();
|
||||
void onAudiosSelect();
|
||||
void onLinksSelect();
|
||||
|
||||
void onForwardCancel(QObject *obj = 0);
|
||||
|
||||
@ -477,7 +480,7 @@ private:
|
||||
void feedUpdate(const MTPUpdate &update);
|
||||
|
||||
void updateReceived(const mtpPrime *from, const mtpPrime *end);
|
||||
void handleUpdates(const MTPUpdates &updates);
|
||||
void handleUpdates(const MTPUpdates &updates, uint64 randomId = 0);
|
||||
bool updateFail(const RPCError &e);
|
||||
|
||||
void usernameResolveDone(QPair<bool, QString> toProfileStartToken, const MTPUser &result);
|
||||
@ -543,7 +546,7 @@ private:
|
||||
enum PtsSkippedQueue {
|
||||
SkippedUpdate,
|
||||
SkippedUpdates,
|
||||
SkippedSentMessage,
|
||||
// SkippedSentMessage,
|
||||
SkippedStatedMessage,
|
||||
SkippedStatedMessages
|
||||
};
|
||||
@ -554,7 +557,7 @@ private:
|
||||
QMap<uint64, PtsSkippedQueue> _byPtsQueue;
|
||||
QMap<uint64, MTPUpdate> _byPtsUpdate;
|
||||
QMap<uint64, MTPUpdates> _byPtsUpdates;
|
||||
QMap<uint64, MTPmessages_SentMessage> _byPtsSentMessage;
|
||||
// QMap<uint64, MTPmessages_SentMessage> _byPtsSentMessage;
|
||||
SingleTimer _byPtsTimer;
|
||||
|
||||
QMap<int32, MTPUpdates> _bySeqUpdates;
|
||||
|
@ -2812,7 +2812,7 @@ int32 MTProtoConnectionPrivate::handleOneReceived(const mtpPrime *from, const mt
|
||||
mtpRequestId fakeRequestId = sessionData->nextFakeRequestId();
|
||||
haveReceived.insert(fakeRequestId, mtpResponse(update)); // notify main process about new updates
|
||||
|
||||
if (cons != mtpc_updatesTooLong && cons != mtpc_updateShortMessage && cons != mtpc_updateShortChatMessage && cons != mtpc_updateShort && cons != mtpc_updatesCombined && cons != mtpc_updates) {
|
||||
if (cons != mtpc_updatesTooLong && cons != mtpc_updateShortMessage && cons != mtpc_updateShortChatMessage && cons != mtpc_updateShortSentMessage && cons != mtpc_updateShort && cons != mtpc_updatesCombined && cons != mtpc_updates) {
|
||||
LOG(("Message Error: unknown constructor %1").arg(cons)); // maybe new api?..
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ enum {
|
||||
MTPDmessage_flag_out = (1 << 1),
|
||||
MTPDmessage_flag_notify_by_from = (1 << 4),
|
||||
MTPDmessage_flag_media_unread = (1 << 5),
|
||||
MTPDmessage_flag_HAS_TEXT_LINKS = (1 << 31), // client side flag for having links
|
||||
|
||||
MTPmessages_SendMessage_flag_skipWebPage = (1 << 1),
|
||||
|
||||
|
@ -366,7 +366,7 @@ static const mtpTypeId mtpLayers[] = {
|
||||
mtpc_invokeWithLayer17,
|
||||
mtpc_invokeWithLayer18,
|
||||
}, mtpLayerMaxSingle = sizeof(mtpLayers) / sizeof(mtpLayers[0]);
|
||||
static const mtpPrime mtpCurrentLayer = 34;
|
||||
static const mtpPrime mtpCurrentLayer = 36;
|
||||
|
||||
template <typename bareT>
|
||||
class MTPBoxed : public bareT {
|
||||
|
@ -655,7 +655,8 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 1: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -673,7 +674,8 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 2: to.add(" duration: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" w: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" h: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" mime_type: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" caption: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -1213,29 +1215,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geoChat:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geoChat");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" venue: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" geo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" participants_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 8: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 9: to.add(" checked_in: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 10: to.add(" version: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_chatFull:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -1346,7 +1325,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 6: to.add(" reply_to_msg_id: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_to_msg_id) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 3 IN FIELD flags ]"); } break;
|
||||
case 7: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 8: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 9: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 9: to.add(" media: "); ++stages.back(); if (flag & MTPDmessage::flag_media) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||
case 10: to.add(" reply_markup: "); ++stages.back(); if (flag & MTPDmessage::flag_reply_markup) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 11: to.add(" entities: "); ++stages.back(); if (flag & MTPDmessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
@ -1566,24 +1545,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageActionGeoChatCreate:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messageActionGeoChatCreate");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messageActionGeoChatCheckin:
|
||||
to.add("{ messageActionGeoChatCheckin }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_messageActionChatJoinedByLink:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -1840,19 +1801,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
to.add("{ inputNotifyAll }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
|
||||
case mtpc_inputNotifyGeoChatPeer:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputNotifyGeoChatPeer");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputPeerNotifyEventsEmpty:
|
||||
to.add("{ inputPeerNotifyEventsEmpty }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
@ -2025,20 +1973,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_chatLocated:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ chatLocated");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" distance: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_contacts_link:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -2194,43 +2128,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messages_sentMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messages_sentMessage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" entities: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messages_sentMessageLink:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ messages_sentMessageLink");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" links: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messages_chats:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -2487,19 +2384,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_updateNewGeoChatMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ updateNewGeoChatMessage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_updateNewEncryptedMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -2899,6 +2783,25 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_updateShortSentMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ updateShortSentMessage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" flags: "); ++stages.back(); if (start >= end) throw Exception("start >= end in flags"); else flags.back() = *start; types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" pts: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" pts_count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" media: "); ++stages.back(); if (flag & MTPDupdateShortSentMessage::flag_media) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||
case 6: to.add(" entities: "); ++stages.back(); if (flag & MTPDupdateShortSentMessage::flag_entities) { types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_photos_photos:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -3051,132 +2954,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_inputGeoChat:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ inputGeoChat");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" access_hash: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geoChatMessageEmpty:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geoChatMessageEmpty");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geoChatMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geoChatMessage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geoChatMessageService:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geoChatMessageService");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" chat_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" from_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" action: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_statedMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_statedMessage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" message: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" seq: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_located:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_located");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" results: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_messages:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_messages");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_messagesSlice:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_messagesSlice");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" count: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" messages: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" chats: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" users: "); ++stages.back(); types.push_back(00); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_encryptedChatEmpty:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -4025,6 +3802,7 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
case 12: to.add(" embed_height: "); ++stages.back(); if (flag & MTPDwebPage::flag_embed_height) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
|
||||
case 13: to.add(" duration: "); ++stages.back(); if (flag & MTPDwebPage::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
|
||||
case 14: to.add(" author: "); ++stages.back(); if (flag & MTPDwebPage::flag_author) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 8 IN FIELD flags ]"); } break;
|
||||
case 15: to.add(" document: "); ++stages.back(); if (flag & MTPDwebPage::flag_document) { types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 9 IN FIELD flags ]"); } break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
@ -4863,20 +4641,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_setTyping:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_setTyping");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" typing: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messages_discardEncryption:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
@ -5785,19 +5549,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_getFullChat:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_getFullChat");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_updates_getState:
|
||||
to.add("{ updates_getState }"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back();
|
||||
break;
|
||||
@ -5941,159 +5692,6 @@ void mtpTextSerializeType(MTPStringLogger &to, const mtpPrime *&from, const mtpP
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_getLocated:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_getLocated");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" radius: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_getRecents:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_getRecents");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_search:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_search");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" q: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" filter: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" min_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 4: to.add(" max_date: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 5: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 6: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 7: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_getHistory:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_getHistory");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" offset: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" max_id: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" limit: "); ++stages.back(); types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_checkin:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_checkin");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_editChatTitle:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_editChatTitle");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_editChatPhoto:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_editChatPhoto");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" photo: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_sendMessage:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_sendMessage");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" message: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_sendMedia:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_sendMedia");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" peer: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" media: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" random_id: "); ++stages.back(); types.push_back(mtpc_long); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_geochats_createGeoChat:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
} else {
|
||||
to.add("{ geochats_createGeoChat");
|
||||
to.add("\n").addSpaces(lev);
|
||||
}
|
||||
switch (stage) {
|
||||
case 0: to.add(" title: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 1: to.add(" geo_point: "); ++stages.back(); types.push_back(0); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 2: to.add(" address: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
case 3: to.add(" venue: "); ++stages.back(); types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); break;
|
||||
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case mtpc_messages_getDhConfig:
|
||||
if (stage) {
|
||||
to.add(",\n").addSpaces(lev);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -146,8 +146,8 @@ inputMediaUploadedPhoto#f7aff1c0 file:InputFile caption:string = InputMedia;
|
||||
inputMediaPhoto#e9bfb4f3 id:InputPhoto caption:string = InputMedia;
|
||||
inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia;
|
||||
inputMediaContact#a6e45987 phone_number:string first_name:string last_name:string = InputMedia;
|
||||
inputMediaUploadedVideo#e13fd4bc file:InputFile duration:int w:int h:int caption:string = InputMedia;
|
||||
inputMediaUploadedThumbVideo#96fb97dc file:InputFile thumb:InputFile duration:int w:int h:int caption:string = InputMedia;
|
||||
inputMediaUploadedVideo#82713fdf file:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
|
||||
inputMediaUploadedThumbVideo#7780ddf9 file:InputFile thumb:InputFile duration:int w:int h:int mime_type:string caption:string = InputMedia;
|
||||
inputMediaVideo#936a4ebd id:InputVideo caption:string = InputMedia;
|
||||
|
||||
inputChatPhotoEmpty#1ca48f57 = InputChatPhoto;
|
||||
@ -212,7 +212,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
|
||||
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
|
||||
|
||||
messageEmpty#83e5de54 id:int = Message;
|
||||
message#f07814c8 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> = Message;
|
||||
message#2bebfa86 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> = Message;
|
||||
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
|
||||
|
||||
messageMediaEmpty#3ded6320 = MessageMedia;
|
||||
@ -283,8 +283,6 @@ contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
|
||||
|
||||
contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
|
||||
|
||||
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
|
||||
|
||||
contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
|
||||
|
||||
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
|
||||
@ -303,8 +301,6 @@ messages.dialogsSlice#71e094f3 count:int dialogs:Vector<Dialog> messages:Vector<
|
||||
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
|
||||
|
||||
messages.sentMessage#8a99d8e0 id:int date:int media:MessageMedia entities:Vector<MessageEntity> pts:int pts_count:int = messages.SentMessage;
|
||||
|
||||
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
|
||||
|
||||
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
|
||||
@ -365,30 +361,6 @@ help.noAppUpdate#c45a6536 = help.AppUpdate;
|
||||
|
||||
help.inviteText#18cb9f78 message:string = help.InviteText;
|
||||
|
||||
messages.sentMessageLink#35a1a663 id:int date:int media:MessageMedia pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.SentMessage;
|
||||
|
||||
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
|
||||
|
||||
inputNotifyGeoChatPeer#4d8ddec8 peer:InputGeoChat = InputNotifyPeer;
|
||||
|
||||
geoChat#75eaea5a id:int access_hash:long title:string address:string venue:string geo:GeoPoint photo:ChatPhoto participants_count:int date:int checked_in:Bool version:int = Chat;
|
||||
|
||||
geoChatMessageEmpty#60311a9b chat_id:int id:int = GeoChatMessage;
|
||||
geoChatMessage#4505f8e1 chat_id:int id:int from_id:int date:int message:string media:MessageMedia = GeoChatMessage;
|
||||
geoChatMessageService#d34fa24e chat_id:int id:int from_id:int date:int action:MessageAction = GeoChatMessage;
|
||||
|
||||
geochats.statedMessage#17b1578b message:GeoChatMessage chats:Vector<Chat> users:Vector<User> seq:int = geochats.StatedMessage;
|
||||
|
||||
geochats.located#48feb267 results:Vector<ChatLocated> messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Located;
|
||||
|
||||
geochats.messages#d1526db1 messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
|
||||
geochats.messagesSlice#bc5863e8 count:int messages:Vector<GeoChatMessage> chats:Vector<Chat> users:Vector<User> = geochats.Messages;
|
||||
|
||||
messageActionGeoChatCreate#6f038ebc title:string address:string = MessageAction;
|
||||
messageActionGeoChatCheckin#c7d53de = MessageAction;
|
||||
|
||||
updateNewGeoChatMessage#5a68e3f7 message:GeoChatMessage = Update;
|
||||
|
||||
wallPaperSolid#63117f24 id:int title:string bg_color:int color:int = WallPaper;
|
||||
|
||||
updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update;
|
||||
@ -546,7 +518,7 @@ updateWebPage#2cc36971 webpage:WebPage = Update;
|
||||
|
||||
webPageEmpty#eb1477e8 id:long = WebPage;
|
||||
webPagePending#c586da1c id:long date:int = WebPage;
|
||||
webPage#a31ea0b5 flags:# id:long url:string display_url:string type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string = WebPage;
|
||||
webPage#ca820ed7 flags:# id:long url:string display_url:string type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document = WebPage;
|
||||
|
||||
messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
|
||||
|
||||
@ -621,6 +593,8 @@ messageEntityCode#28a20571 offset:int length:int = MessageEntity;
|
||||
messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
|
||||
messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
|
||||
|
||||
updateShortSentMessage#11f1331c flags:# id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -672,7 +646,7 @@ messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHis
|
||||
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
|
||||
messages.receivedMessages#5a954c0 max_id:int = Vector<ReceivedNotifyMessage>;
|
||||
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
|
||||
messages.sendMessage#df12390 flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = messages.SentMessage;
|
||||
messages.sendMessage#fa88427a flags:# peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> = Updates;
|
||||
messages.sendMedia#c8f16791 flags:# peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia random_id:long reply_markup:flags.2?ReplyMarkup = Updates;
|
||||
messages.forwardMessages#55e1728d peer:InputPeer id:Vector<int> random_id:Vector<long> = Updates;
|
||||
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
|
||||
@ -703,20 +677,6 @@ photos.getUserPhotos#91cd32a8 user_id:InputUser offset:int max_id:long limit:int
|
||||
|
||||
messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates;
|
||||
messages.sendBroadcast#bf73f4da contacts:Vector<InputUser> random_id:Vector<long> message:string media:InputMedia = Updates;
|
||||
|
||||
geochats.getLocated#7f192d8f geo_point:InputGeoPoint radius:int limit:int = geochats.Located;
|
||||
geochats.getRecents#e1427e6f offset:int limit:int = geochats.Messages;
|
||||
geochats.checkin#55b3e8fb peer:InputGeoChat = geochats.StatedMessage;
|
||||
geochats.getFullChat#6722dd6f peer:InputGeoChat = messages.ChatFull;
|
||||
geochats.editChatTitle#4c8e2273 peer:InputGeoChat title:string address:string = geochats.StatedMessage;
|
||||
geochats.editChatPhoto#35d81a95 peer:InputGeoChat photo:InputChatPhoto = geochats.StatedMessage;
|
||||
geochats.search#cfcdc44d peer:InputGeoChat q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = geochats.Messages;
|
||||
geochats.getHistory#b53f7a68 peer:InputGeoChat offset:int max_id:int limit:int = geochats.Messages;
|
||||
geochats.setTyping#8b8a729 peer:InputGeoChat typing:Bool = Bool;
|
||||
geochats.sendMessage#61b0044 peer:InputGeoChat message:string random_id:long = geochats.StatedMessage;
|
||||
geochats.sendMedia#b8f0deff peer:InputGeoChat media:InputMedia random_id:long = geochats.StatedMessage;
|
||||
geochats.createGeoChat#e092e16 title:string geo_point:InputGeoPoint address:string venue:string = geochats.StatedMessage;
|
||||
|
||||
messages.getDhConfig#26cf8950 version:int random_length:int = messages.DhConfig;
|
||||
messages.requestEncryption#f64daf43 user_id:InputUser random_id:int g_a:bytes = EncryptedChat;
|
||||
messages.acceptEncryption#3dbc0415 peer:InputEncryptedChat g_b:bytes key_fingerprint:long = EncryptedChat;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -25,9 +25,14 @@ public:
|
||||
|
||||
OverviewInner(OverviewWidget *overview, ScrollArea *scroll, const PeerData *peer, MediaOverviewType type);
|
||||
|
||||
void activate();
|
||||
|
||||
void clear();
|
||||
int32 itemTop(MsgId msgId) const;
|
||||
|
||||
bool preloadLocal();
|
||||
void preloadMore();
|
||||
|
||||
bool event(QEvent *e);
|
||||
void touchEvent(QTouchEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
@ -73,8 +78,10 @@ public:
|
||||
public slots:
|
||||
|
||||
void onUpdateSelected();
|
||||
void showLinkTip();
|
||||
|
||||
void openContextUrl();
|
||||
void copyContextUrl();
|
||||
void cancelContextDownload();
|
||||
void showContextInFolder();
|
||||
void saveContextFile();
|
||||
@ -85,12 +92,19 @@ public slots:
|
||||
void forwardMessage();
|
||||
void selectMessage();
|
||||
|
||||
void onSearchUpdate();
|
||||
void onCancel();
|
||||
bool onCancelSearch();
|
||||
|
||||
void onMenuDestroy(QObject *obj);
|
||||
void onTouchSelect();
|
||||
void onTouchScrollTimer();
|
||||
|
||||
void onDragExec();
|
||||
|
||||
bool onSearchMessages(bool searchCache = false);
|
||||
void onNeedSearchMessages();
|
||||
|
||||
private:
|
||||
|
||||
void fixItemIndex(int32 ¤t, MsgId msgId) const;
|
||||
@ -122,11 +136,11 @@ private:
|
||||
|
||||
// photos
|
||||
int32 _photosInRow, _photosToAdd, _vsize;
|
||||
typedef struct {
|
||||
struct CachedSize {
|
||||
int32 vsize;
|
||||
bool medium;
|
||||
QPixmap pix;
|
||||
} CachedSize;
|
||||
};
|
||||
typedef QMap<PhotoData*, CachedSize> CachedSizes;
|
||||
CachedSizes _cached;
|
||||
bool _selMode;
|
||||
@ -134,23 +148,75 @@ private:
|
||||
// audio documents
|
||||
int32 _audioLeft, _audioWidth, _audioHeight;
|
||||
|
||||
// other
|
||||
typedef struct _CachedItem {
|
||||
_CachedItem() : msgid(0), y(0) {
|
||||
// shared links
|
||||
int32 _linksLeft, _linksWidth;
|
||||
struct Link {
|
||||
Link() : width(0) {
|
||||
}
|
||||
_CachedItem(MsgId msgid, const QDate &date, int32 y) : msgid(msgid), date(date), y(y) {
|
||||
Link(const QString &url, const QString &text) : url(url), text(text), width(st::msgFont->m.width(text)) {
|
||||
}
|
||||
QString url, text;
|
||||
int32 width;
|
||||
};
|
||||
struct CachedLink {
|
||||
CachedLink() : titleWidth(0), page(0), pixw(0), pixh(0), text(st::msgMinWidth) {
|
||||
}
|
||||
CachedLink(HistoryItem *item);
|
||||
int32 countHeight(int32 w);
|
||||
|
||||
QString title, letter;
|
||||
int32 titleWidth;
|
||||
WebPageData *page;
|
||||
int32 pixw, pixh;
|
||||
Text text;
|
||||
QVector<Link> urls;
|
||||
};
|
||||
typedef QMap<MsgId, CachedLink*> CachedLinks;
|
||||
CachedLinks _links;
|
||||
FlatInput _search;
|
||||
IconedButton _cancelSearch;
|
||||
QVector<MsgId> _results;
|
||||
int32 _itemsToBeLoaded;
|
||||
|
||||
QTimer _searchTimer;
|
||||
QString _searchQuery;
|
||||
bool _inSearch, _searchFull;
|
||||
mtpRequestId _searchRequest;
|
||||
History::MediaOverview _searchResults;
|
||||
MsgId _lastSearchId;
|
||||
int32 _searchedCount;
|
||||
void searchReceived(bool fromStart, const MTPmessages_Messages &result, mtpRequestId req);
|
||||
bool searchFailed(const RPCError &error, mtpRequestId req);
|
||||
|
||||
typedef QMap<QString, MTPmessages_Messages> SearchCache;
|
||||
SearchCache _searchCache;
|
||||
|
||||
typedef QMap<mtpRequestId, QString> SearchQueries;
|
||||
SearchQueries _searchQueries;
|
||||
|
||||
CachedLink *cachedLink(HistoryItem *item);
|
||||
|
||||
// other
|
||||
struct CachedItem {
|
||||
CachedItem() : msgid(0), y(0) {
|
||||
}
|
||||
CachedItem(MsgId msgid, const QDate &date, int32 y) : msgid(msgid), date(date), y(y) {
|
||||
}
|
||||
MsgId msgid;
|
||||
QDate date;
|
||||
int32 y;
|
||||
} CachedItem;
|
||||
CachedLink *link;
|
||||
};
|
||||
typedef QVector<CachedItem> CachedItems;
|
||||
CachedItems _items;
|
||||
|
||||
int32 _width, _height, _minHeight, _addToY;
|
||||
|
||||
QTimer _linkTipTimer;
|
||||
|
||||
// selection support, like in HistoryWidget
|
||||
Qt::CursorShape _cursor;
|
||||
HistoryCursorState _cursorState;
|
||||
typedef QMap<MsgId, uint32> SelectedItems;
|
||||
SelectedItems _selected;
|
||||
enum DragAction {
|
||||
@ -166,9 +232,14 @@ private:
|
||||
int32 _dragItemIndex;
|
||||
MsgId _mousedItem;
|
||||
int32 _mousedItemIndex;
|
||||
int32 _lnkOverIndex, _lnkDownIndex; // for OverviewLinks, 0 - none, -1 - photo or title, > 0 - lnk index
|
||||
uint16 _dragSymbol;
|
||||
bool _dragWasInactive;
|
||||
|
||||
QString urlByIndex(MsgId msgid, int32 index, int32 lnkIndex, bool *fullShown = 0) const;
|
||||
bool urlIsEmail(const QString &url) const;
|
||||
|
||||
QString _contextMenuUrl;
|
||||
TextLinkPtr _contextMenuLnk;
|
||||
|
||||
MsgId _dragSelFrom, _dragSelTo;
|
||||
@ -202,6 +273,7 @@ public:
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
void scrollBy(int32 add);
|
||||
void scrollReset();
|
||||
|
||||
void paintTopBar(QPainter &p, float64 over, int32 decreaseWidth);
|
||||
void topBarShadowParams(int32 &x, float64 &o);
|
||||
|
@ -59,10 +59,14 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
// shared media
|
||||
_allMediaTypes(false),
|
||||
_mediaShowAll(this, lang(lng_profile_show_all_types)),
|
||||
_mediaPhotos(this, QString()),
|
||||
_mediaVideos(this, QString()),
|
||||
_mediaDocuments(this, QString()),
|
||||
_mediaAudios(this, QString()),
|
||||
|
||||
// actions
|
||||
_searchInPeer(this, lang(lng_profile_search_messages)),
|
||||
_clearHistory(this, lang(lng_profile_clear_history)),
|
||||
_deleteConversation(this, lang(_peer->chat ? lng_profile_clear_and_exit : lng_profile_delete_conversation)),
|
||||
_wasBlocked(_peerUser ? _peerUser->blocked : UserBlockUnknown),
|
||||
_blockRequest(0),
|
||||
_blockUser(this, lang((_peerUser && _peerUser->botInfo) ? lng_profile_block_bot : lng_profile_block_user), st::btnRedLink),
|
||||
|
||||
// actions
|
||||
_searchInPeer(this, lang(lng_profile_search_messages)),
|
||||
@ -86,7 +90,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
if (_peerUser->blocked == UserIsBlocked) {
|
||||
_blockUser.setText(lang(_peerUser->botInfo ? lng_profile_unblock_bot : lng_profile_unblock_user));
|
||||
}
|
||||
_phoneText = App::formatPhone(_peerUser->phone);
|
||||
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(App::userFromPeer(_peerUser->id)) : _peerUser->phone);
|
||||
PhotoData *userPhoto = (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) ? App::photo(_peerUser->photoId) : 0;
|
||||
if (userPhoto && userPhoto->date) {
|
||||
_photoLink = TextLinkPtr(new PhotoLink(userPhoto, _peer));
|
||||
@ -161,14 +165,11 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, const Pee
|
||||
|
||||
// shared media
|
||||
connect(&_mediaShowAll, SIGNAL(clicked()), this, SLOT(onMediaShowAll()));
|
||||
connect(&_mediaPhotos, SIGNAL(clicked()), this, SLOT(onMediaPhotos()));
|
||||
connect(&_mediaVideos, SIGNAL(clicked()), this, SLOT(onMediaVideos()));
|
||||
connect(&_mediaDocuments, SIGNAL(clicked()), this, SLOT(onMediaDocuments()));
|
||||
connect(&_mediaAudios, SIGNAL(clicked()), this, SLOT(onMediaAudios()));
|
||||
_mediaLinks[OverviewPhotos] = &_mediaPhotos;
|
||||
_mediaLinks[OverviewVideos] = &_mediaVideos;
|
||||
_mediaLinks[OverviewDocuments] = &_mediaDocuments;
|
||||
_mediaLinks[OverviewAudios] = &_mediaAudios;
|
||||
connect((_mediaButtons[OverviewPhotos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaPhotos()));
|
||||
connect((_mediaButtons[OverviewVideos] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaVideos()));
|
||||
connect((_mediaButtons[OverviewDocuments] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaDocuments()));
|
||||
connect((_mediaButtons[OverviewAudios] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaAudios()));
|
||||
connect((_mediaButtons[OverviewLinks] = new LinkButton(this, QString())), SIGNAL(clicked()), this, SLOT(onMediaLinks()));
|
||||
App::main()->preloadOverviews(_peer);
|
||||
|
||||
// actions
|
||||
@ -216,7 +217,7 @@ void ProfileInner::loadProfilePhotos(int32 yFrom) {
|
||||
int32 yTo = yFrom + (parentWidget() ? parentWidget()->height() : App::wnd()->height()) * 5;
|
||||
MTP::clearLoaderPriorities();
|
||||
|
||||
int32 partfrom = _mediaAudios.y() + _mediaAudios.height() + st::profileHeaderSkip;
|
||||
int32 partfrom = _mediaButtons[OverviewAudios]->y() + _mediaButtons[OverviewAudios]->height() + st::profileHeaderSkip;
|
||||
yFrom -= partfrom;
|
||||
yTo -= partfrom;
|
||||
|
||||
@ -361,6 +362,10 @@ void ProfileInner::onMediaAudios() {
|
||||
App::main()->showMediaOverview(_peer, OverviewAudios);
|
||||
}
|
||||
|
||||
void ProfileInner::onMediaLinks() {
|
||||
App::main()->showMediaOverview(_peer, OverviewLinks);
|
||||
}
|
||||
|
||||
void ProfileInner::onInvitationLink() {
|
||||
QApplication::clipboard()->setText(_peerChat->invitationUrl);
|
||||
App::wnd()->showLayer(new ConfirmBox(lang(lng_group_invite_copied), true));
|
||||
@ -437,7 +442,7 @@ void ProfileInner::peerUpdated(PeerData *data) {
|
||||
if (data == _peer) {
|
||||
PhotoData *photo = 0;
|
||||
if (_peerUser) {
|
||||
_phoneText = App::formatPhone(_peerUser->phone);
|
||||
_phoneText = App::formatPhone(_peerUser->phone.isEmpty() ? App::phoneFromSharedContact(App::userFromPeer(_peerUser->id)) : _peerUser->phone);
|
||||
if (_peerUser->photoId && _peerUser->photoId != UnknownPeerPhotoId) photo = App::photo(_peerUser->photoId);
|
||||
if (_wasBlocked != _peerUser->blocked) {
|
||||
_wasBlocked = _peerUser->blocked;
|
||||
@ -652,7 +657,7 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
if (!_allMediaTypes) {
|
||||
break;
|
||||
}
|
||||
top += _mediaLinks[i]->height() + st::setLittleSkip;
|
||||
top += _mediaButtons[i]->height() + st::setLittleSkip;
|
||||
}
|
||||
}
|
||||
if (_allMediaTypes) {
|
||||
@ -660,13 +665,13 @@ void ProfileInner::paintEvent(QPaintEvent *e) {
|
||||
top -= st::setLittleSkip;
|
||||
} else {
|
||||
p.drawText(_left, top + st::linkFont->ascent, lang(oneState < 0 ? lng_profile_loading : lng_profile_no_media));
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
top += _mediaButtons[OverviewPhotos]->height();
|
||||
}
|
||||
} else {
|
||||
if (!oneState) {
|
||||
p.drawText(_left, top + st::linkFont->ascent, lang(lng_profile_no_media));
|
||||
}
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
top += _mediaButtons[OverviewPhotos]->height();
|
||||
}
|
||||
|
||||
// actions
|
||||
@ -934,13 +939,23 @@ void ProfileInner::resizeEvent(QResizeEvent *e) {
|
||||
if (_allMediaTypes) {
|
||||
int32 count = (_hist->_overviewCount[i] > 0) ? _hist->_overviewCount[i] : (_hist->_overviewCount[i] == 0 ? _hist->_overview[i].size() : -1);
|
||||
if (count > 0) {
|
||||
if (wasCount) top += _mediaLinks[i]->height() + st::setLittleSkip;
|
||||
if (wasCount) top += _mediaButtons[i]->height() + st::setLittleSkip;
|
||||
wasCount = count;
|
||||
}
|
||||
}
|
||||
_mediaLinks[i]->move(_left, top);
|
||||
_mediaButtons[i]->move(_left, top);
|
||||
}
|
||||
top += _mediaButtons[OverviewPhotos]->height();
|
||||
|
||||
// actions
|
||||
top += st::profileHeaderSkip;
|
||||
_searchInPeer.move(_left, top); top += _searchInPeer.height() + st::setLittleSkip;
|
||||
_clearHistory.move(_left, top); top += _clearHistory.height() + st::setLittleSkip;
|
||||
_deleteConversation.move(_left, top); top += _deleteConversation.height();
|
||||
if (_peerUser && App::userFromPeer(_peerUser->id) != MTP::authedId()) {
|
||||
top += st::setSectionSkip;
|
||||
_blockUser.move(_left, top); top += _blockUser.height();
|
||||
}
|
||||
top += _mediaLinks[OverviewPhotos]->height();
|
||||
|
||||
// actions
|
||||
top += st::profileHeaderSkip;
|
||||
@ -1131,17 +1146,17 @@ void ProfileInner::showAll() {
|
||||
if (count > 0 || count < 0) {
|
||||
first = true;
|
||||
} else if (!_allMediaTypes) {
|
||||
_mediaLinks[i]->hide();
|
||||
_mediaButtons[i]->hide();
|
||||
continue;
|
||||
}
|
||||
if (count > 0) {
|
||||
_mediaLinks[i]->setText(overviewLinkText(i, count));
|
||||
_mediaLinks[i]->show();
|
||||
_mediaButtons[i]->setText(overviewLinkText(i, count));
|
||||
_mediaButtons[i]->show();
|
||||
} else {
|
||||
_mediaLinks[i]->hide();
|
||||
_mediaButtons[i]->hide();
|
||||
}
|
||||
} else {
|
||||
_mediaLinks[i]->hide();
|
||||
_mediaButtons[i]->hide();
|
||||
}
|
||||
}
|
||||
if (_allMediaTypes || !manyCounts) {
|
||||
@ -1208,6 +1223,7 @@ QString ProfileInner::overviewLinkText(int32 type, int32 count) {
|
||||
case OverviewVideos: return lng_profile_videos(lt_count, count);
|
||||
case OverviewDocuments: return lng_profile_files(lt_count, count);
|
||||
case OverviewAudios: return lng_profile_audios(lt_count, count);
|
||||
case OverviewLinks: return lng_profile_shared_links(lt_count, count);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ public slots:
|
||||
void onMediaVideos();
|
||||
void onMediaDocuments();
|
||||
void onMediaAudios();
|
||||
void onMediaLinks();
|
||||
|
||||
void onMenuDestroy(QObject *obj);
|
||||
void onCopyPhone();
|
||||
@ -149,8 +150,8 @@ private:
|
||||
|
||||
// shared media
|
||||
bool _allMediaTypes;
|
||||
LinkButton _mediaShowAll, _mediaPhotos, _mediaVideos, _mediaDocuments, _mediaAudios;
|
||||
LinkButton *_mediaLinks[OverviewCount];
|
||||
LinkButton _mediaShowAll;
|
||||
LinkButton *_mediaButtons[OverviewCount];
|
||||
QString overviewLinkText(int32 type, int32 count);
|
||||
|
||||
// actions
|
||||
|
@ -252,8 +252,8 @@ namespace {
|
||||
#define GTK_ALPHA 3
|
||||
|
||||
QImage _trayIconImageGen() {
|
||||
int32 counter = App::histories().unreadFull, counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = (App::histories().unreadMuted >= counter);
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
if (_trayIconImage.isNull() || _trayIconImage.width() != _trayIconSize || muted != _trayIconMuted || counterSlice != _trayIconCount) {
|
||||
if (_trayIconImageBack.isNull() || _trayIconImageBack.width() != _trayIconSize) {
|
||||
_trayIconImageBack = App::wnd()->iconLarge().scaled(_trayIconSize, _trayIconSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
@ -288,8 +288,8 @@ namespace {
|
||||
}
|
||||
|
||||
QString _trayIconImageFile() {
|
||||
int32 counter = App::histories().unreadFull, counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = (App::histories().unreadMuted >= counter);
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted), counterSlice = (counter >= 1000) ? (1000 + (counter % 100)) : counter;
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
QString name = cWorkingDir() + qsl("tdata/ticons/ico%1_%2_%3.png").arg(muted ? "mute" : "").arg(_trayIconSize).arg(counterSlice);
|
||||
QFileInfo info(name);
|
||||
@ -641,7 +641,7 @@ void PsMainWindow::psUpdateIndicator() {
|
||||
void PsMainWindow::psUpdateCounter() {
|
||||
setWindowIcon(wndIcon);
|
||||
|
||||
int32 counter = App::histories().unreadFull;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
|
||||
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
|
||||
if (_psUnityLauncherEntry) {
|
||||
@ -665,8 +665,10 @@ void PsMainWindow::psUpdateCounter() {
|
||||
ps_gtk_status_icon_set_from_pixbuf(_trayIcon, _trayPixbuf);
|
||||
}
|
||||
} else if (trayIcon) {
|
||||
int32 counter = App::histories().unreadFull;
|
||||
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
QIcon iconSmall;
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true), Qt::ColorOnly));
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true), Qt::ColorOnly));
|
||||
|
@ -174,7 +174,7 @@ void _placeCounter(QImage &img, int size, int count, style::color bg, style::col
|
||||
}
|
||||
|
||||
void PsMainWindow::psUpdateCounter() {
|
||||
int32 counter = App::histories().unreadFull;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
|
||||
setWindowTitle((counter > 0) ? qsl("Telegram (%1)").arg(counter) : qsl("Telegram"));
|
||||
setWindowIcon(wndIcon);
|
||||
@ -183,14 +183,16 @@ void PsMainWindow::psUpdateCounter() {
|
||||
_private.setWindowBadge(counter ? cnt : QString());
|
||||
|
||||
if (trayIcon) {
|
||||
bool dm = objc_darkMode(), important = (App::histories().unreadMuted < counter);
|
||||
style::color bg = important ? st::counterBG : st::counterMuteBG;
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
bool dm = objc_darkMode();
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
QIcon icon;
|
||||
QImage img(psTrayIcon(dm)), imgsel(psTrayIcon(true));
|
||||
img.detach();
|
||||
imgsel.detach();
|
||||
int32 size = cRetina() ? 44 : 22;
|
||||
_placeCounter(img, size, counter, bg, (dm && !important) ? st::counterMacInvColor : st::counterColor);
|
||||
_placeCounter(img, size, counter, bg, (dm && muted) ? st::counterMacInvColor : st::counterColor);
|
||||
_placeCounter(imgsel, size, counter, st::white, st::counterMacInvColor);
|
||||
icon.addPixmap(QPixmap::fromImage(img, Qt::ColorOnly));
|
||||
icon.addPixmap(QPixmap::fromImage(imgsel, Qt::ColorOnly), QIcon::Selected);
|
||||
|
@ -119,7 +119,7 @@ namespace {
|
||||
};
|
||||
typedef QMap<StorageKey, ToastImage> ToastImages;
|
||||
ToastImages toastImages;
|
||||
bool toastImageCreated = false;
|
||||
bool toastImageSaved = false;
|
||||
|
||||
HWND createTaskbarHider() {
|
||||
HINSTANCE appinst = (HINSTANCE)GetModuleHandle(0);
|
||||
@ -1117,8 +1117,10 @@ static HICON _qt_createHIcon(const QIcon &icon, int xSize, int ySize) {
|
||||
}
|
||||
|
||||
void PsMainWindow::psUpdateCounter() {
|
||||
int32 counter = App::histories().unreadFull;
|
||||
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
QIcon iconSmall, iconBig;
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(16, counter, bg, true), Qt::ColorOnly));
|
||||
iconSmall.addPixmap(QPixmap::fromImage(iconWithCounter(32, counter, bg, true), Qt::ColorOnly));
|
||||
@ -2123,12 +2125,14 @@ bool psShowOpenWithMenu(int x, int y, const QString &file) {
|
||||
}
|
||||
|
||||
void psOpenFile(const QString &name, bool openWith) {
|
||||
std::wstring wname = QDir::toNativeSeparators(name).toStdWString();
|
||||
bool mailtoScheme = name.startsWith(qstr("mailto:"));
|
||||
std::wstring wname = mailtoScheme ? name.toStdWString() : QDir::toNativeSeparators(name).toStdWString();
|
||||
|
||||
if (openWith && useOpenAs) {
|
||||
if (shOpenWithDialog) {
|
||||
OPENASINFO info;
|
||||
info.oaifInFlags = OAIF_ALLOW_REGISTRATION | OAIF_REGISTER_EXT | OAIF_EXEC;
|
||||
if (mailtoScheme) info.oaifInFlags |= OAIF_FILE_IS_URI | OAIF_URL_PROTOCOL;
|
||||
info.pcszClass = NULL;
|
||||
info.pcszFile = wname.c_str();
|
||||
shOpenWithDialog(0, &info);
|
||||
@ -2149,7 +2153,7 @@ void psStart() {
|
||||
}
|
||||
|
||||
void psFinish() {
|
||||
if (toastImageCreated) {
|
||||
if (toastImageSaved) {
|
||||
psDeleteDir(cWorkingDir() + qsl("tdata/temp"));
|
||||
}
|
||||
}
|
||||
@ -2709,7 +2713,7 @@ QString toastImage(const StorageKey &key, PeerData *peer) {
|
||||
App::wnd()->iconLarge().save(v.path, "PNG");
|
||||
}
|
||||
i = toastImages.insert(key, v);
|
||||
toastImageCreated = true;
|
||||
toastImageSaved = true;
|
||||
}
|
||||
return i->path;
|
||||
}
|
||||
@ -2805,9 +2809,6 @@ bool CreateToast(PeerData *peer, int32 msgId, bool showpix, const QString &title
|
||||
if (j != i->cend()) {
|
||||
toastNotifier->Hide(j->p.Get());
|
||||
i->erase(j);
|
||||
if (i->isEmpty()) {
|
||||
toastNotifications.erase(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
hr = toastNotifier->Show(toast.Get());
|
||||
|
@ -40,6 +40,7 @@ QString gLangErrors;
|
||||
QString gDialogLastPath, gDialogHelperPath; // optimize QFileDialog
|
||||
|
||||
bool gSoundNotify = true;
|
||||
bool gIncludeMuted = true;
|
||||
bool gDesktopNotify = true;
|
||||
DBINotifyView gNotifyView = dbinvShowPreview;
|
||||
bool gWindowsNotifications = true;
|
||||
|
@ -96,6 +96,7 @@ DeclareSetting(QPixmapPointer, ChatDogImage);
|
||||
DeclareSetting(bool, TileBackground);
|
||||
|
||||
DeclareSetting(bool, SoundNotify);
|
||||
DeclareSetting(bool, IncludeMuted);
|
||||
DeclareSetting(bool, NeedConfigResave);
|
||||
DeclareSetting(bool, DesktopNotify);
|
||||
DeclareSetting(DBINotifyView, NotifyView);
|
||||
|
@ -124,12 +124,15 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
_messagePreview(this, lang(lng_settings_show_preview), cNotifyView() <= dbinvShowPreview),
|
||||
_windowsNotifications(this, lang(lng_settings_use_windows), cWindowsNotifications()),
|
||||
_soundNotify(this, lang(lng_settings_sound_notify), cSoundNotify()),
|
||||
_includeMuted(this, lang(lng_settings_include_muted), cIncludeMuted()),
|
||||
|
||||
// general
|
||||
_changeLanguage(this, lang(lng_settings_change_lang)),
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
_autoUpdate(this, lang(lng_settings_auto_update), cAutoUpdate()),
|
||||
_checkNow(this, lang(lng_settings_check_now)),
|
||||
_restartNow(this, lang(lng_settings_update_now)),
|
||||
#endif
|
||||
|
||||
_supportTray(cSupportTray()),
|
||||
_workmodeTray(this, lang(lng_settings_workmode_tray), (cWorkMode() == dbiwmTrayOnly || cWorkMode() == dbiwmWindowAndTray)),
|
||||
@ -223,12 +226,15 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
connect(&_messagePreview, SIGNAL(changed()), this, SLOT(onMessagePreview()));
|
||||
connect(&_windowsNotifications, SIGNAL(changed()), this, SLOT(onWindowsNotifications()));
|
||||
connect(&_soundNotify, SIGNAL(changed()), this, SLOT(onSoundNotify()));
|
||||
connect(&_includeMuted, SIGNAL(changed()), this, SLOT(onIncludeMuted()));
|
||||
|
||||
// general
|
||||
connect(&_changeLanguage, SIGNAL(clicked()), this, SLOT(onChangeLanguage()));
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
connect(&_autoUpdate, SIGNAL(changed()), this, SLOT(onAutoUpdate()));
|
||||
connect(&_checkNow, SIGNAL(clicked()), this, SLOT(onCheckNow()));
|
||||
connect(&_restartNow, SIGNAL(clicked()), this, SLOT(onRestartNow()));
|
||||
#endif
|
||||
|
||||
connect(&_workmodeTray, SIGNAL(changed()), this, SLOT(onWorkmodeTray()));
|
||||
connect(&_workmodeWindow, SIGNAL(changed()), this, SLOT(onWorkmodeWindow()));
|
||||
@ -246,11 +252,13 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
_newVersionText = lang(lng_settings_update_ready) + ' ';
|
||||
_newVersionWidth = st::linkFont->m.width(_newVersionText);
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
connect(App::app(), SIGNAL(updateChecking()), this, SLOT(onUpdateChecking()));
|
||||
connect(App::app(), SIGNAL(updateLatest()), this, SLOT(onUpdateLatest()));
|
||||
connect(App::app(), SIGNAL(updateDownloading(qint64,qint64)), this, SLOT(onUpdateDownloading(qint64,qint64)));
|
||||
connect(App::app(), SIGNAL(updateReady()), this, SLOT(onUpdateReady()));
|
||||
connect(App::app(), SIGNAL(updateFailed()), this, SLOT(onUpdateFailed()));
|
||||
#endif
|
||||
|
||||
// chat options
|
||||
connect(&_replaceEmojis, SIGNAL(changed()), this, SLOT(onReplaceEmojis()));
|
||||
@ -303,6 +311,7 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
|
||||
updateOnlineDisplay();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
switch (App::app()->updatingState()) {
|
||||
case Application::UpdatingDownload:
|
||||
setUpdatingState(UpdatingDownload, true);
|
||||
@ -311,6 +320,9 @@ SettingsInner::SettingsInner(SettingsWidget *parent) : QWidget(parent),
|
||||
case Application::UpdatingReady: setUpdatingState(UpdatingReady, true); break;
|
||||
default: setUpdatingState(UpdatingNone, true); break;
|
||||
}
|
||||
#else
|
||||
_updatingState = UpdatingNone;
|
||||
#endif
|
||||
|
||||
updateConnectionType();
|
||||
|
||||
@ -421,7 +433,8 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
top += _windowsNotifications.height() + st::setSectionSkip;
|
||||
}
|
||||
top += _soundNotify.height();
|
||||
top += _soundNotify.height() + st::setSectionSkip;
|
||||
top += _includeMuted.height();
|
||||
}
|
||||
|
||||
// general
|
||||
@ -430,6 +443,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
p.drawText(_left + st::setHeaderLeft, top + st::setHeaderTop + st::setHeaderFont->ascent, lang(lng_settings_section_general));
|
||||
top += st::setHeaderSkip;
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
top += _autoUpdate.height();
|
||||
QString textToDraw;
|
||||
if (cAutoUpdate()) {
|
||||
@ -448,6 +462,7 @@ void SettingsInner::paintEvent(QPaintEvent *e) {
|
||||
p.setPen(st::setVersionColor->p);
|
||||
p.drawText(_left + st::setVersionLeft, top + st::setVersionTop + st::linkFont->ascent, textToDraw);
|
||||
top += st::setVersionHeight;
|
||||
#endif
|
||||
|
||||
if (cPlatform() == dbipWindows) {
|
||||
top += _workmodeTray.height() + st::setLittleSkip;
|
||||
@ -650,16 +665,19 @@ void SettingsInner::resizeEvent(QResizeEvent *e) {
|
||||
if (App::wnd()->psHasNativeNotifications() && cPlatform() == dbipWindows) {
|
||||
_windowsNotifications.move(_left, top); top += _windowsNotifications.height() + st::setSectionSkip;
|
||||
}
|
||||
_soundNotify.move(_left, top); top += _soundNotify.height();
|
||||
_soundNotify.move(_left, top); top += _soundNotify.height() + st::setSectionSkip;
|
||||
_includeMuted.move(_left, top); top += _includeMuted.height();
|
||||
}
|
||||
|
||||
// general
|
||||
top += st::setHeaderSkip;
|
||||
_changeLanguage.move(_left + st::setWidth - _changeLanguage.width(), top - st::setHeaderSkip + st::setHeaderTop + st::setHeaderFont->ascent - st::linkFont->ascent);
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
_autoUpdate.move(_left, top);
|
||||
_checkNow.move(_left + st::setWidth - _checkNow.width(), top + st::cbDefFlat.textTop); top += _autoUpdate.height();
|
||||
_restartNow.move(_left + st::setWidth - _restartNow.width(), top + st::setVersionTop);
|
||||
top += st::setVersionHeight;
|
||||
#endif
|
||||
|
||||
if (cPlatform() == dbipWindows) {
|
||||
_workmodeTray.move(_left, top); top += _workmodeTray.height() + st::setLittleSkip;
|
||||
@ -962,18 +980,22 @@ void SettingsInner::showAll() {
|
||||
_windowsNotifications.hide();
|
||||
}
|
||||
_soundNotify.show();
|
||||
_includeMuted.show();
|
||||
} else {
|
||||
_desktopNotify.hide();
|
||||
_senderName.hide();
|
||||
_messagePreview.hide();
|
||||
_windowsNotifications.hide();
|
||||
_soundNotify.hide();
|
||||
_includeMuted.hide();
|
||||
}
|
||||
|
||||
// general
|
||||
_changeLanguage.show();
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
_autoUpdate.show();
|
||||
setUpdatingState(_updatingState, true);
|
||||
#endif
|
||||
if (cPlatform() == dbipWindows) {
|
||||
_workmodeTray.show();
|
||||
_workmodeWindow.show();
|
||||
@ -1219,6 +1241,7 @@ void SettingsInner::onUpdateLocalStorage() {
|
||||
update();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void SettingsInner::onAutoUpdate() {
|
||||
cSetAutoUpdate(!cAutoUpdate());
|
||||
Local::writeSettings();
|
||||
@ -1244,8 +1267,10 @@ void SettingsInner::onCheckNow() {
|
||||
cSetLastUpdateCheck(0);
|
||||
App::app()->startUpdateCheck();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SettingsInner::onRestartNow() {
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
checkReadyUpdate();
|
||||
if (_updatingState == UpdatingReady) {
|
||||
cSetRestartingUpdate(true);
|
||||
@ -1253,6 +1278,10 @@ void SettingsInner::onRestartNow() {
|
||||
cSetRestarting(true);
|
||||
cSetRestartingToSettings(true);
|
||||
}
|
||||
#else
|
||||
cSetRestarting(true);
|
||||
cSetRestartingToSettings(true);
|
||||
#endif
|
||||
App::quit();
|
||||
}
|
||||
|
||||
@ -1420,6 +1449,12 @@ void SettingsInner::onSoundNotify() {
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
void SettingsInner::onIncludeMuted() {
|
||||
cSetIncludeMuted(_includeMuted.checked());
|
||||
if (App::wnd()) App::wnd()->updateCounter();
|
||||
Local::writeUserSettings();
|
||||
}
|
||||
|
||||
void SettingsInner::onWindowsNotifications() {
|
||||
cSetWindowsNotifications(!cWindowsNotifications());
|
||||
App::wnd()->notifyClearFast();
|
||||
@ -1636,6 +1671,7 @@ void SettingsInner::onTempDirClearFailed(int task) {
|
||||
update();
|
||||
}
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void SettingsInner::setUpdatingState(UpdatingState state, bool force) {
|
||||
if (_updatingState != state || force) {
|
||||
_updatingState = state;
|
||||
@ -1689,6 +1725,7 @@ void SettingsInner::onUpdateReady() {
|
||||
void SettingsInner::onUpdateFailed() {
|
||||
setUpdatingState(UpdatingFail);
|
||||
}
|
||||
#endif
|
||||
|
||||
void SettingsInner::onPhotoUpdateStart() {
|
||||
showAll();
|
||||
|
@ -97,8 +97,10 @@ public slots:
|
||||
void onUpdatePhoto();
|
||||
void onUpdatePhotoCancel();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void onAutoUpdate();
|
||||
void onCheckNow();
|
||||
#endif
|
||||
void onRestartNow();
|
||||
|
||||
void onPasscode();
|
||||
@ -123,6 +125,7 @@ public slots:
|
||||
void onScaleChange();
|
||||
|
||||
void onSoundNotify();
|
||||
void onIncludeMuted();
|
||||
void onDesktopNotify();
|
||||
void onSenderName();
|
||||
void onMessagePreview();
|
||||
@ -149,11 +152,13 @@ public slots:
|
||||
|
||||
void onLocalStorageClear();
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void onUpdateChecking();
|
||||
void onUpdateLatest();
|
||||
void onUpdateDownloading(qint64 ready, qint64 total);
|
||||
void onUpdateReady();
|
||||
void onUpdateFailed();
|
||||
#endif
|
||||
|
||||
void onShowSessions();
|
||||
|
||||
@ -202,12 +207,14 @@ private:
|
||||
LinkButton _chooseUsername;
|
||||
|
||||
// notifications
|
||||
FlatCheckbox _desktopNotify, _senderName, _messagePreview, _windowsNotifications, _soundNotify;
|
||||
FlatCheckbox _desktopNotify, _senderName, _messagePreview, _windowsNotifications, _soundNotify, _includeMuted;
|
||||
|
||||
// general
|
||||
LinkButton _changeLanguage;
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
FlatCheckbox _autoUpdate;
|
||||
LinkButton _checkNow, _restartNow;
|
||||
#endif
|
||||
bool _supportTray; // cSupportTray() value on settings create
|
||||
FlatCheckbox _workmodeTray, _workmodeWindow;
|
||||
FlatCheckbox _autoStart, _startMinimized, _sendToMenu;
|
||||
@ -280,8 +287,10 @@ private:
|
||||
void offPasswordDone(const MTPBool &result);
|
||||
bool offPasswordFail(const RPCError &error);
|
||||
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
void setUpdatingState(UpdatingState state, bool force = false);
|
||||
void setDownloadProgress(qint64 ready, qint64 total);
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
@ -774,8 +774,8 @@ QString DocumentData::already(bool check) {
|
||||
return location.name;
|
||||
}
|
||||
|
||||
WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, int32 duration, const QString &author, int32 pendingTill) :
|
||||
id(id), type(type), url(url), displayUrl(displayUrl), siteName(siteName), title(title), description(description), duration(duration), author(author), photo(photo), pendingTill(pendingTill) {
|
||||
WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill) :
|
||||
id(id), type(type), url(url), displayUrl(displayUrl), siteName(siteName), title(title), description(description), duration(duration), author(author), photo(photo), doc(doc), pendingTill(pendingTill) {
|
||||
}
|
||||
|
||||
void PeerLink::onClick(Qt::MouseButton button) const {
|
||||
|
@ -548,6 +548,19 @@ struct DocumentData {
|
||||
if (sticker()) sticker()->img->forget();
|
||||
replyPreview->forget();
|
||||
}
|
||||
ImagePtr makeReplyPreview() {
|
||||
if (replyPreview->isNull() && !thumb->isNull()) {
|
||||
if (thumb->loaded()) {
|
||||
int w = thumb->width(), h = thumb->height();
|
||||
if (w <= 0) w = 1;
|
||||
if (h <= 0) h = 1;
|
||||
replyPreview = ImagePtr(w > h ? thumb->pix(w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : thumb->pix(st::msgReplyBarSize.height()), "PNG");
|
||||
} else {
|
||||
thumb->load();
|
||||
}
|
||||
}
|
||||
return replyPreview;
|
||||
}
|
||||
|
||||
void save(const QString &toFile);
|
||||
|
||||
@ -687,7 +700,7 @@ inline WebPageType toWebPageType(const QString &type) {
|
||||
}
|
||||
|
||||
struct WebPageData {
|
||||
WebPageData(const WebPageId &id, WebPageType type = WebPageArticle, const QString &url = QString(), const QString &displayUrl = QString(), const QString &siteName = QString(), const QString &title = QString(), const QString &description = QString(), PhotoData *photo = 0, int32 duration = 0, const QString &author = QString(), int32 pendingTill = -1);
|
||||
WebPageData(const WebPageId &id, WebPageType type = WebPageArticle, const QString &url = QString(), const QString &displayUrl = QString(), const QString &siteName = QString(), const QString &title = QString(), const QString &description = QString(), PhotoData *photo = 0, DocumentData *doc = 0, int32 duration = 0, const QString &author = QString(), int32 pendingTill = -1);
|
||||
|
||||
void forget() {
|
||||
if (photo) photo->forget();
|
||||
@ -699,6 +712,7 @@ struct WebPageData {
|
||||
int32 duration;
|
||||
QString author;
|
||||
PhotoData *photo;
|
||||
DocumentData *doc;
|
||||
int32 pendingTill;
|
||||
};
|
||||
|
||||
|
@ -143,7 +143,9 @@ UpdateBtn::UpdateBtn(QWidget *parent, Window *window, const QString &text) : Sys
|
||||
}
|
||||
|
||||
void UpdateBtn::onClick() {
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
checkReadyUpdate();
|
||||
#endif
|
||||
if (App::app()->updatingState() == Application::UpdatingReady) {
|
||||
cSetRestartingUpdate(true);
|
||||
} else {
|
||||
|
@ -80,7 +80,9 @@ TitleWidget::TitleWidget(Window *window)
|
||||
connect(&_contacts, SIGNAL(clicked()), this, SLOT(onContacts()));
|
||||
connect(&_about, SIGNAL(clicked()), this, SLOT(onAbout()));
|
||||
connect(wnd->windowHandle(), SIGNAL(windowStateChanged(Qt::WindowState)), this, SLOT(stateChanged(Qt::WindowState)));
|
||||
#ifndef TDESKTOP_DISABLE_AUTOUPDATE
|
||||
connect(App::app(), SIGNAL(updateReady()), this, SLOT(showUpdateBtn()));
|
||||
#endif
|
||||
|
||||
if (cPlatform() != dbipWindows) {
|
||||
_minimize.hide();
|
||||
@ -256,8 +258,10 @@ void TitleWidget::updateWideMode() {
|
||||
void TitleWidget::updateCounter() {
|
||||
if (cWideMode() || !MTP::authedId()) return;
|
||||
|
||||
int32 counter = App::histories().unreadFull;
|
||||
style::color bg = (App::histories().unreadMuted < counter) ? st::counterBG : st::counterMuteBG;
|
||||
int32 counter = App::histories().unreadFull - (cIncludeMuted() ? 0 : App::histories().unreadMuted);
|
||||
bool muted = cIncludeMuted() ? (App::histories().unreadMuted >= counter) : false;
|
||||
|
||||
style::color bg = muted ? st::counterMuteBG : st::counterBG;
|
||||
|
||||
if (counter > 0) {
|
||||
int32 size = cRetina() ? -32 : -16;
|
||||
|
@ -275,6 +275,7 @@ enum DataBlockId {
|
||||
dbiTryIPv6 = 0x28,
|
||||
dbiSongVolume = 0x29,
|
||||
dbiWindowsNotifications = 0x30,
|
||||
dbiIncludeMuted = 0x31,
|
||||
|
||||
dbiEncryptedWithSalt = 333,
|
||||
dbiEncrypted = 444,
|
||||
|
@ -11,7 +11,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.8.51</string>
|
||||
<string>0.8.55</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
|
Binary file not shown.
@ -1477,6 +1477,20 @@
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\gui\countrycodeinput.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing countrycodeinput.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\ffmpeg-2.6.3" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.5.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.5.0\QtGui" "-fstdafx.h" "-f../../SourceFiles/gui/countrycodeinput.h"</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Moc%27ing countrycodeinput.h...</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">Moc%27ing countrycodeinput.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\libogg-1.3.2\include" "-I.\..\..\Libraries\opus\include" "-I.\..\..\Libraries\opusfile\include" "-I.\..\..\Libraries\mpg123-1.22.1\ports\MSVC++" "-I.\..\..\Libraries\mpg123-1.22.1\src\libmpg123" "-I.\..\..\Libraries\faad2-2.7\include" "-I.\..\..\Libraries\faad2-2.7\common\mp4ff" "-I.\..\..\Libraries\ffmpeg-2.6.3" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.5.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.5.0\QtGui" "-fstdafx.h" "-f../../SourceFiles/gui/countrycodeinput.h"</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\OpenSSL-Win32\include" "-I.\..\..\Libraries\ffmpeg-2.6.3" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.5.0\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.5.0\QtGui" "-fstdafx.h" "-f../../SourceFiles/gui/countrycodeinput.h"</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="SourceFiles\gui\phoneinput.h">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing phoneinput.h...</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
|
||||
@ -2151,4 +2165,4 @@
|
||||
<UserProperties UicDir=".\GeneratedFiles" MocDir=".\GeneratedFiles\$(ConfigurationName)" MocOptions="" RccDir=".\GeneratedFiles" lupdateOnBuild="1" lupdateOptions="" lreleaseOptions="" Qt5Version_x0020_Win32="$(DefaultQtVersion)" />
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -1707,7 +1707,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.51;
|
||||
CURRENT_PROJECT_VERSION = 0.8.55;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
@ -1725,7 +1725,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 0.8.51;
|
||||
CURRENT_PROJECT_VERSION = 0.8.55;
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = fast;
|
||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||
@ -1751,10 +1751,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.51;
|
||||
CURRENT_PROJECT_VERSION = 0.8.55;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.51;
|
||||
DYLIB_CURRENT_VERSION = 0.8.55;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
@ -1885,10 +1885,10 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
CODE_SIGN_IDENTITY = "";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 0.8.51;
|
||||
CURRENT_PROJECT_VERSION = 0.8.55;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DYLIB_COMPATIBILITY_VERSION = 0.8;
|
||||
DYLIB_CURRENT_VERSION = 0.8.51;
|
||||
DYLIB_CURRENT_VERSION = 0.8.55;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||
|
@ -2,9 +2,11 @@ cd ../../
|
||||
tx pull -fa
|
||||
cd translations/telegram-desktop.langstrings/
|
||||
for file in *.strings; do
|
||||
iconv -f "UTF-16LE" -t "UTF-8" "$file" > "../../tdesktop/Telegram/SourceFiles/langs/lang_$file.tmp"
|
||||
awk '{ if (NR==1) sub(/^\xef\xbb\xbf/,""); sub(/
/,""); print }' "../../tdesktop/Telegram/SourceFiles/langs/lang_$file.tmp" > "../../tdesktop/Telegram/SourceFiles/langs/lang_$file"
|
||||
rm "../../tdesktop/Telegram/SourceFiles/langs/lang_$file.tmp"
|
||||
if [ "$file" != "es_419.strings" ]; then
|
||||
iconv -f "UTF-16LE" -t "UTF-8" "$file" > "../../tdesktop/Telegram/SourceFiles/langs/lang_$file.tmp"
|
||||
awk '{ if (NR==1) sub(/^\xef\xbb\xbf/,""); sub(/
/,""); print }' "../../tdesktop/Telegram/SourceFiles/langs/lang_$file.tmp" > "../../tdesktop/Telegram/SourceFiles/langs/lang_$file"
|
||||
rm "../../tdesktop/Telegram/SourceFiles/langs/lang_$file.tmp"
|
||||
fi
|
||||
done
|
||||
cd ../../tdesktop/Telegram/
|
||||
touch SourceFiles/telegram.qrc
|
||||
|
@ -1,2 +1,2 @@
|
||||
echo 0.8 8051 0.8.51 0
|
||||
echo 0.8 8055 0.8.55 0
|
||||
# AppVersionStrMajor AppVersion AppVersionStr DevChannel
|
||||
|
@ -11566,6 +11566,22 @@ index da0ba27..1d42b79 100644
|
||||
void QWindowsXpFileDialogHelper::selectNameFilter(const QString &f)
|
||||
{
|
||||
m_data.setSelectedNameFilter(f); // Dialog cannot be updated at run-time.
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp b/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp
|
||||
index cc697ba..8e15e86 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp
|
||||
+++ b/qtbase/src/plugins/platforms/windows/qwindowsservices.cpp
|
||||
@@ -125,8 +125,9 @@ static inline bool launchMail(const QUrl &url)
|
||||
}
|
||||
// Pass the url as the parameter. Should use QProcess::startDetached(),
|
||||
// but that cannot handle a Windows command line [yet].
|
||||
- command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
- if (debug)
|
||||
+ if (command.indexOf(QStringLiteral("%1")) < 0) return false;
|
||||
+ command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
+ if (debug)
|
||||
qDebug() << __FUNCTION__ << "Launching" << command;
|
||||
//start the process
|
||||
PROCESS_INFORMATION pi;
|
||||
diff --git a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp b/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
index 543c081..d80429b 100644
|
||||
--- a/qtbase/src/plugins/platforms/windows/qwindowswindow.cpp
|
||||
|
@ -0,0 +1,160 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#define QT_NO_URL_CAST_FROM_STRING
|
||||
#include "qwindowsservices.h"
|
||||
#include "qtwindows_additional.h"
|
||||
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
|
||||
#include <shlobj.h>
|
||||
#ifndef Q_OS_WINCE
|
||||
# include <intshcut.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
static inline bool shellExecute(const QUrl &url)
|
||||
{
|
||||
#ifndef Q_OS_WINCE
|
||||
const QString nativeFilePath =
|
||||
url.isLocalFile() ? QDir::toNativeSeparators(url.toLocalFile()) : url.toString(QUrl::FullyEncoded);
|
||||
const quintptr result = (quintptr)ShellExecute(0, 0, (wchar_t*)nativeFilePath.utf16(), 0, 0, SW_SHOWNORMAL);
|
||||
// ShellExecute returns a value greater than 32 if successful
|
||||
if (result <= 32) {
|
||||
qWarning("ShellExecute '%s' failed (error %s).", qPrintable(url.toString()), qPrintable(QString::number(result)));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
Q_UNUSED(url);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Retrieve the commandline for the default mail client. It contains a
|
||||
// placeholder %1 for the URL. The default key used below is the
|
||||
// command line for the mailto: shell command.
|
||||
static inline QString mailCommand()
|
||||
{
|
||||
enum { BufferSize = sizeof(wchar_t) * MAX_PATH };
|
||||
|
||||
const wchar_t mailUserKey[] = L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\mailto\\UserChoice";
|
||||
|
||||
wchar_t command[MAX_PATH] = {0};
|
||||
// Check if user has set preference, otherwise use default.
|
||||
HKEY handle;
|
||||
QString keyName;
|
||||
if (!RegOpenKeyEx(HKEY_CURRENT_USER, mailUserKey, 0, KEY_READ, &handle)) {
|
||||
DWORD bufferSize = BufferSize;
|
||||
if (!RegQueryValueEx(handle, L"Progid", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize))
|
||||
keyName = QString::fromWCharArray(command);
|
||||
RegCloseKey(handle);
|
||||
}
|
||||
if (keyName.isEmpty())
|
||||
keyName = QStringLiteral("mailto");
|
||||
keyName += QStringLiteral("\\Shell\\Open\\Command");
|
||||
if (debug)
|
||||
qDebug() << __FUNCTION__ << "keyName=" << keyName;
|
||||
command[0] = 0;
|
||||
if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, (const wchar_t*)keyName.utf16(), 0, KEY_READ, &handle)) {
|
||||
DWORD bufferSize = BufferSize;
|
||||
RegQueryValueEx(handle, L"", 0, 0, reinterpret_cast<unsigned char*>(command), &bufferSize);
|
||||
RegCloseKey(handle);
|
||||
}
|
||||
if (!command[0])
|
||||
return QString();
|
||||
#ifndef Q_OS_WINCE
|
||||
wchar_t expandedCommand[MAX_PATH] = {0};
|
||||
return ExpandEnvironmentStrings(command, expandedCommand, MAX_PATH) ?
|
||||
QString::fromWCharArray(expandedCommand) : QString::fromWCharArray(command);
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool launchMail(const QUrl &url)
|
||||
{
|
||||
QString command = mailCommand();
|
||||
if (command.isEmpty()) {
|
||||
qWarning("Cannot launch '%s': There is no mail program installed.", qPrintable(url.toString()));
|
||||
return false;
|
||||
}
|
||||
//Make sure the path for the process is in quotes
|
||||
const QChar doubleQuote = QLatin1Char('"');
|
||||
if (!command.startsWith(doubleQuote)) {
|
||||
const int exeIndex = command.indexOf(QStringLiteral(".exe "), 0, Qt::CaseInsensitive);
|
||||
if (exeIndex != -1) {
|
||||
command.insert(exeIndex + 4, doubleQuote);
|
||||
command.prepend(doubleQuote);
|
||||
}
|
||||
}
|
||||
// Pass the url as the parameter. Should use QProcess::startDetached(),
|
||||
// but that cannot handle a Windows command line [yet].
|
||||
if (command.indexOf(QStringLiteral("%1")) < 0) return false;
|
||||
command.replace(QStringLiteral("%1"), url.toString(QUrl::FullyEncoded));
|
||||
if (debug)
|
||||
qDebug() << __FUNCTION__ << "Launching" << command;
|
||||
//start the process
|
||||
PROCESS_INFORMATION pi;
|
||||
ZeroMemory(&pi, sizeof(pi));
|
||||
STARTUPINFO si;
|
||||
ZeroMemory(&si, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
if (!CreateProcess(NULL, (wchar_t*)command.utf16(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
|
||||
qErrnoWarning("Unable to launch '%s'", qPrintable(command));
|
||||
return false;
|
||||
}
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QWindowsServices::openUrl(const QUrl &url)
|
||||
{
|
||||
const QString scheme = url.scheme();
|
||||
if (scheme == QLatin1String("mailto") && launchMail(url))
|
||||
return true;
|
||||
return shellExecute(url);
|
||||
}
|
||||
|
||||
bool QWindowsServices::openDocument(const QUrl &url)
|
||||
{
|
||||
return shellExecute(url);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
Loading…
Reference in New Issue
Block a user