mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-25 10:44:41 +02:00
Move many widget classes to lib_ui.
This commit is contained in:
parent
dda587a2fc
commit
849deb57e2
189 changed files with 3750 additions and 2572 deletions
|
@ -72,8 +72,11 @@ linkCropLimit: 360px;
|
||||||
linkFont: normalFont;
|
linkFont: normalFont;
|
||||||
linkOverFont: font(fsize underline);
|
linkOverFont: font(fsize underline);
|
||||||
|
|
||||||
dateRadius: 6px;
|
roundRadiusLarge: 6px;
|
||||||
buttonRadius: 3px;
|
roundRadiusSmall: 3px;
|
||||||
|
|
||||||
|
dateRadius: roundRadiusLarge;
|
||||||
|
buttonRadius: roundRadiusSmall;
|
||||||
|
|
||||||
setLittleSkip: 9px;
|
setLittleSkip: 9px;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "api/api_sending.h"
|
#include "api/api_sending.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
|
@ -73,12 +74,12 @@ void SendExistingMedia(
|
||||||
|
|
||||||
auto caption = TextWithEntities{
|
auto caption = TextWithEntities{
|
||||||
message.textWithTags.text,
|
message.textWithTags.text,
|
||||||
ConvertTextTagsToEntities(message.textWithTags.tags)
|
TextUtilities::ConvertTextTagsToEntities(message.textWithTags.tags)
|
||||||
};
|
};
|
||||||
TextUtilities::Trim(caption);
|
TextUtilities::Trim(caption);
|
||||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
auto sentEntities = EntitiesToMTP(
|
||||||
caption.entities,
|
caption.entities,
|
||||||
TextUtilities::ConvertOption::SkipLocal);
|
ConvertOption::SkipLocal);
|
||||||
if (!sentEntities.v.isEmpty()) {
|
if (!sentEntities.v.isEmpty()) {
|
||||||
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
sendFlags |= MTPmessages_SendMedia::Flag::f_entities;
|
||||||
}
|
}
|
||||||
|
|
129
Telegram/SourceFiles/api/api_text_entities.cpp
Normal file
129
Telegram/SourceFiles/api/api_text_entities.cpp
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
|
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_user.h"
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace TextUtilities;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities) {
|
||||||
|
auto result = EntitiesInText();
|
||||||
|
if (!entities.isEmpty()) {
|
||||||
|
result.reserve(entities.size());
|
||||||
|
for_const (auto &entity, entities) {
|
||||||
|
switch (entity.type()) {
|
||||||
|
case mtpc_messageEntityUrl: { auto &d = entity.c_messageEntityUrl(); result.push_back({ EntityType::Url, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityTextUrl: { auto &d = entity.c_messageEntityTextUrl(); result.push_back({ EntityType::CustomUrl, d.voffset().v, d.vlength().v, Clean(qs(d.vurl())) }); } break;
|
||||||
|
case mtpc_messageEntityEmail: { auto &d = entity.c_messageEntityEmail(); result.push_back({ EntityType::Email, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityHashtag: { auto &d = entity.c_messageEntityHashtag(); result.push_back({ EntityType::Hashtag, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityCashtag: { auto &d = entity.c_messageEntityCashtag(); result.push_back({ EntityType::Cashtag, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityPhone: break; // Skipping phones.
|
||||||
|
case mtpc_messageEntityMention: { auto &d = entity.c_messageEntityMention(); result.push_back({ EntityType::Mention, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityMentionName: {
|
||||||
|
auto &d = entity.c_messageEntityMentionName();
|
||||||
|
auto data = [&d] {
|
||||||
|
if (auto user = Auth().data().userLoaded(d.vuser_id().v)) {
|
||||||
|
return MentionNameDataFromFields({
|
||||||
|
d.vuser_id().v,
|
||||||
|
user->accessHash() });
|
||||||
|
}
|
||||||
|
return MentionNameDataFromFields(d.vuser_id().v);
|
||||||
|
};
|
||||||
|
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data() });
|
||||||
|
} break;
|
||||||
|
case mtpc_inputMessageEntityMentionName: {
|
||||||
|
auto &d = entity.c_inputMessageEntityMentionName();
|
||||||
|
auto data = ([&d]() -> QString {
|
||||||
|
if (d.vuser_id().type() == mtpc_inputUserSelf) {
|
||||||
|
return MentionNameDataFromFields(Auth().userId());
|
||||||
|
} else if (d.vuser_id().type() == mtpc_inputUser) {
|
||||||
|
auto &user = d.vuser_id().c_inputUser();
|
||||||
|
return MentionNameDataFromFields({ user.vuser_id().v, user.vaccess_hash().v });
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
})();
|
||||||
|
if (!data.isEmpty()) {
|
||||||
|
result.push_back({ EntityType::MentionName, d.voffset().v, d.vlength().v, data });
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case mtpc_messageEntityBotCommand: { auto &d = entity.c_messageEntityBotCommand(); result.push_back({ EntityType::BotCommand, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityBold: { auto &d = entity.c_messageEntityBold(); result.push_back({ EntityType::Bold, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityItalic: { auto &d = entity.c_messageEntityItalic(); result.push_back({ EntityType::Italic, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityUnderline: { auto &d = entity.c_messageEntityUnderline(); result.push_back({ EntityType::Underline, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityStrike: { auto &d = entity.c_messageEntityStrike(); result.push_back({ EntityType::StrikeOut, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityCode: { auto &d = entity.c_messageEntityCode(); result.push_back({ EntityType::Code, d.voffset().v, d.vlength().v }); } break;
|
||||||
|
case mtpc_messageEntityPre: { auto &d = entity.c_messageEntityPre(); result.push_back({ EntityType::Pre, d.voffset().v, d.vlength().v, Clean(qs(d.vlanguage())) }); } break;
|
||||||
|
// #TODO entities
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
MTPVector<MTPMessageEntity> EntitiesToMTP(
|
||||||
|
const EntitiesInText &entities,
|
||||||
|
ConvertOption option) {
|
||||||
|
auto v = QVector<MTPMessageEntity>();
|
||||||
|
v.reserve(entities.size());
|
||||||
|
for_const (auto &entity, entities) {
|
||||||
|
if (entity.length() <= 0) continue;
|
||||||
|
if (option == ConvertOption::SkipLocal
|
||||||
|
&& entity.type() != EntityType::Bold
|
||||||
|
&& entity.type() != EntityType::Italic
|
||||||
|
&& entity.type() != EntityType::Underline
|
||||||
|
&& entity.type() != EntityType::StrikeOut
|
||||||
|
&& entity.type() != EntityType::Code // #TODO entities
|
||||||
|
&& entity.type() != EntityType::Pre
|
||||||
|
&& entity.type() != EntityType::MentionName
|
||||||
|
&& entity.type() != EntityType::CustomUrl) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto offset = MTP_int(entity.offset());
|
||||||
|
auto length = MTP_int(entity.length());
|
||||||
|
switch (entity.type()) {
|
||||||
|
case EntityType::Url: v.push_back(MTP_messageEntityUrl(offset, length)); break;
|
||||||
|
case EntityType::CustomUrl: v.push_back(MTP_messageEntityTextUrl(offset, length, MTP_string(entity.data()))); break;
|
||||||
|
case EntityType::Email: v.push_back(MTP_messageEntityEmail(offset, length)); break;
|
||||||
|
case EntityType::Hashtag: v.push_back(MTP_messageEntityHashtag(offset, length)); break;
|
||||||
|
case EntityType::Cashtag: v.push_back(MTP_messageEntityCashtag(offset, length)); break;
|
||||||
|
case EntityType::Mention: v.push_back(MTP_messageEntityMention(offset, length)); break;
|
||||||
|
case EntityType::MentionName: {
|
||||||
|
auto inputUser = ([](const QString &data) -> MTPInputUser {
|
||||||
|
auto fields = MentionNameDataToFields(data);
|
||||||
|
if (fields.userId == Auth().userId()) {
|
||||||
|
return MTP_inputUserSelf();
|
||||||
|
} else if (fields.userId) {
|
||||||
|
return MTP_inputUser(MTP_int(fields.userId), MTP_long(fields.accessHash));
|
||||||
|
}
|
||||||
|
return MTP_inputUserEmpty();
|
||||||
|
})(entity.data());
|
||||||
|
if (inputUser.type() != mtpc_inputUserEmpty) {
|
||||||
|
v.push_back(MTP_inputMessageEntityMentionName(offset, length, inputUser));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case EntityType::BotCommand: v.push_back(MTP_messageEntityBotCommand(offset, length)); break;
|
||||||
|
case EntityType::Bold: v.push_back(MTP_messageEntityBold(offset, length)); break;
|
||||||
|
case EntityType::Italic: v.push_back(MTP_messageEntityItalic(offset, length)); break;
|
||||||
|
case EntityType::Underline: v.push_back(MTP_messageEntityUnderline(offset, length)); break;
|
||||||
|
case EntityType::StrikeOut: v.push_back(MTP_messageEntityStrike(offset, length)); break;
|
||||||
|
case EntityType::Code: v.push_back(MTP_messageEntityCode(offset, length)); break; // #TODO entities
|
||||||
|
case EntityType::Pre: v.push_back(MTP_messageEntityPre(offset, length, MTP_string(entity.data()))); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MTP_vector<MTPMessageEntity>(std::move(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Api
|
23
Telegram/SourceFiles/api/api_text_entities.h
Normal file
23
Telegram/SourceFiles/api/api_text_entities.h
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/text/text_entity.h"
|
||||||
|
|
||||||
|
namespace Api {
|
||||||
|
|
||||||
|
EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities);
|
||||||
|
enum class ConvertOption {
|
||||||
|
WithLocal,
|
||||||
|
SkipLocal,
|
||||||
|
};
|
||||||
|
MTPVector<MTPMessageEntity> EntitiesToMTP(
|
||||||
|
const EntitiesInText &entities,
|
||||||
|
ConvertOption option = ConvertOption::WithLocal);
|
||||||
|
|
||||||
|
} // namespace Api
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_web_page.h"
|
#include "data/data_web_page.h"
|
||||||
|
@ -2562,9 +2563,9 @@ void ApiWrap::saveDraftsToCloud() {
|
||||||
if (!textWithTags.tags.isEmpty()) {
|
if (!textWithTags.tags.isEmpty()) {
|
||||||
flags |= MTPmessages_SaveDraft::Flag::f_entities;
|
flags |= MTPmessages_SaveDraft::Flag::f_entities;
|
||||||
}
|
}
|
||||||
auto entities = TextUtilities::EntitiesToMTP(
|
auto entities = Api::EntitiesToMTP(
|
||||||
ConvertTextTagsToEntities(textWithTags.tags),
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||||
TextUtilities::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
const auto draftText = textWithTags.text;
|
const auto draftText = textWithTags.text;
|
||||||
history->setSentDraftText(draftText);
|
history->setSentDraftText(draftText);
|
||||||
|
@ -4830,9 +4831,9 @@ void ApiWrap::editUploadedFile(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
auto sentEntities = Api::EntitiesToMTP(
|
||||||
item->originalText().entities,
|
item->originalText().entities,
|
||||||
TextUtilities::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
auto flagsEditMsg = MTPmessages_EditMessage::Flag::f_message | 0;
|
auto flagsEditMsg = MTPmessages_EditMessage::Flag::f_message | 0;
|
||||||
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
||||||
|
@ -4934,7 +4935,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
auto sending = TextWithEntities();
|
auto sending = TextWithEntities();
|
||||||
auto left = TextWithEntities {
|
auto left = TextWithEntities {
|
||||||
textWithTags.text,
|
textWithTags.text,
|
||||||
ConvertTextTagsToEntities(textWithTags.tags)
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
||||||
};
|
};
|
||||||
auto prepareFlags = Ui::ItemTextOptions(
|
auto prepareFlags = Ui::ItemTextOptions(
|
||||||
history,
|
history,
|
||||||
|
@ -4988,8 +4989,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||||
if (silentPost) {
|
if (silentPost) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
||||||
}
|
}
|
||||||
auto localEntities = TextUtilities::EntitiesToMTP(sending.entities);
|
auto localEntities = Api::EntitiesToMTP(sending.entities);
|
||||||
auto sentEntities = TextUtilities::EntitiesToMTP(sending.entities, TextUtilities::ConvertOption::SkipLocal);
|
auto sentEntities = Api::EntitiesToMTP(
|
||||||
|
sending.entities,
|
||||||
|
Api::ConvertOption::SkipLocal);
|
||||||
if (!sentEntities.v.isEmpty()) {
|
if (!sentEntities.v.isEmpty()) {
|
||||||
sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
||||||
}
|
}
|
||||||
|
@ -5274,9 +5277,9 @@ void ApiWrap::sendMediaWithRandomId(
|
||||||
|
|
||||||
auto caption = item->originalText();
|
auto caption = item->originalText();
|
||||||
TextUtilities::Trim(caption);
|
TextUtilities::Trim(caption);
|
||||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
auto sentEntities = Api::EntitiesToMTP(
|
||||||
caption.entities,
|
caption.entities,
|
||||||
TextUtilities::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
|
|
||||||
const auto flags = MTPmessages_SendMedia::Flags(0)
|
const auto flags = MTPmessages_SendMedia::Flags(0)
|
||||||
| (replyTo
|
| (replyTo
|
||||||
|
|
|
@ -63,8 +63,6 @@ namespace {
|
||||||
*pressedLinkItem = nullptr,
|
*pressedLinkItem = nullptr,
|
||||||
*mousedItem = nullptr;
|
*mousedItem = nullptr;
|
||||||
|
|
||||||
style::font monofont;
|
|
||||||
|
|
||||||
struct CornersPixmaps {
|
struct CornersPixmaps {
|
||||||
QPixmap p[4];
|
QPixmap p[4];
|
||||||
};
|
};
|
||||||
|
@ -138,14 +136,6 @@ namespace App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tryFontFamily(QString &family, const QString &tryFamily) {
|
|
||||||
if (family.isEmpty()) {
|
|
||||||
if (!QFontInfo(QFont(tryFamily)).family().trimmed().compare(tryFamily, Qt::CaseInsensitive)) {
|
|
||||||
family = tryFamily;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void createMaskCorners() {
|
void createMaskCorners() {
|
||||||
QImage mask[4];
|
QImage mask[4];
|
||||||
prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
|
prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
|
||||||
|
@ -204,16 +194,6 @@ namespace App {
|
||||||
}
|
}
|
||||||
|
|
||||||
void initMedia() {
|
void initMedia() {
|
||||||
if (!::monofont) {
|
|
||||||
QString family;
|
|
||||||
tryFontFamily(family, qsl("Consolas"));
|
|
||||||
tryFontFamily(family, qsl("Liberation Mono"));
|
|
||||||
tryFontFamily(family, qsl("Menlo"));
|
|
||||||
tryFontFamily(family, qsl("Courier"));
|
|
||||||
if (family.isEmpty()) family = QFontDatabase::systemFont(QFontDatabase::FixedFont).family();
|
|
||||||
::monofont = style::font(st::normalFont->f.pixelSize(), 0, family);
|
|
||||||
}
|
|
||||||
|
|
||||||
createCorners();
|
createCorners();
|
||||||
|
|
||||||
using Update = Window::Theme::BackgroundUpdate;
|
using Update = Window::Theme::BackgroundUpdate;
|
||||||
|
@ -293,10 +273,6 @@ namespace App {
|
||||||
mousedItem(nullptr);
|
mousedItem(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const style::font &monofont() {
|
|
||||||
return ::monofont;
|
|
||||||
}
|
|
||||||
|
|
||||||
void quit() {
|
void quit() {
|
||||||
if (quitting()) {
|
if (quitting()) {
|
||||||
return;
|
return;
|
||||||
|
@ -451,15 +427,6 @@ namespace App {
|
||||||
rectWithCorners(p, rect, st::msgInBg, MessageInCorners, corners);
|
rectWithCorners(p, rect, st::msgInBg, MessageInCorners, corners);
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage *cornersMask(ImageRoundRadius radius) {
|
|
||||||
switch (radius) {
|
|
||||||
case ImageRoundRadius::Large: return ::cornersMaskLarge;
|
|
||||||
case ImageRoundRadius::Small:
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return ::cornersMaskSmall;
|
|
||||||
}
|
|
||||||
|
|
||||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
|
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
|
||||||
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
|
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
|
||||||
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
|
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
|
||||||
|
|
|
@ -81,8 +81,6 @@ namespace App {
|
||||||
HistoryView::Element *mousedItem();
|
HistoryView::Element *mousedItem();
|
||||||
void clearMousedItems();
|
void clearMousedItems();
|
||||||
|
|
||||||
const style::font &monofont();
|
|
||||||
|
|
||||||
void initMedia();
|
void initMedia();
|
||||||
void deinitMedia();
|
void deinitMedia();
|
||||||
|
|
||||||
|
@ -106,7 +104,6 @@ namespace App {
|
||||||
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
void complexOverlayRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||||
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
void complexLocationRect(Painter &p, QRect rect, ImageRoundRadius radius, RectParts corners);
|
||||||
|
|
||||||
QImage *cornersMask(ImageRoundRadius radius);
|
|
||||||
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
|
void roundRect(Painter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
|
||||||
inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
|
inline void roundRect(Painter &p, const QRect &rect, style::color bg, RoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
|
||||||
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
|
return roundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
|
||||||
|
|
|
@ -81,6 +81,23 @@ struct pointer_comparator {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline QString FromUtf8Safe(const char *string, int size = -1) {
|
||||||
|
if (!string || !size) {
|
||||||
|
return QString();
|
||||||
|
} else if (size < 0) {
|
||||||
|
size = strlen(string);
|
||||||
|
}
|
||||||
|
const auto result = QString::fromUtf8(string, size);
|
||||||
|
const auto back = result.toUtf8();
|
||||||
|
return (back.size() != size || memcmp(back.constData(), string, size))
|
||||||
|
? QString::fromLocal8Bit(string, size)
|
||||||
|
: result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString FromUtf8Safe(const QByteArray &string) {
|
||||||
|
return FromUtf8Safe(string.constData(), string.size());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
61
Telegram/SourceFiles/base/crc32hash.cpp
Normal file
61
Telegram/SourceFiles/base/crc32hash.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "base/crc32hash.h"
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class Crc32Table {
|
||||||
|
public:
|
||||||
|
Crc32Table() {
|
||||||
|
auto poly = std::uint32_t(0x04c11db7);
|
||||||
|
for (auto i = 0; i != 256; ++i) {
|
||||||
|
_data[i] = reflect(i, 8) << 24;
|
||||||
|
for (auto j = 0; j != 8; ++j) {
|
||||||
|
_data[i] = (_data[i] << 1) ^ (_data[i] & (1 << 31) ? poly : 0);
|
||||||
|
}
|
||||||
|
_data[i] = reflect(_data[i], 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t operator[](int index) const {
|
||||||
|
return _data[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::uint32_t reflect(std::uint32_t val, char ch) {
|
||||||
|
auto result = std::uint32_t(0);
|
||||||
|
for (int i = 1; i < (ch + 1); ++i) {
|
||||||
|
if (val & 1) {
|
||||||
|
result |= 1 << (ch - i);
|
||||||
|
}
|
||||||
|
val >>= 1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t _data[256];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::int32_t crc32(const void *data, int len) {
|
||||||
|
static const auto kTable = Crc32Table();
|
||||||
|
|
||||||
|
const auto buffer = static_cast<const std::uint8_t*>(data);
|
||||||
|
|
||||||
|
auto crc = std::uint32_t(0xffffffff);
|
||||||
|
for (auto i = 0; i != len; ++i) {
|
||||||
|
crc = (crc >> 8) ^ kTable[(crc & 0xFF) ^ buffer[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<std::int32_t>(crc ^ 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace base
|
16
Telegram/SourceFiles/base/crc32hash.h
Normal file
16
Telegram/SourceFiles/base/crc32hash.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
std::int32_t crc32(const void *data, int len);
|
||||||
|
|
||||||
|
} // namespace base
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QPointer>
|
||||||
|
|
||||||
// Smart pointer for QObject*, has move semantics, destroys object if it doesn't have a parent.
|
// Smart pointer for QObject*, has move semantics, destroys object if it doesn't have a parent.
|
||||||
template <typename Object>
|
template <typename Object>
|
||||||
class object_ptr {
|
class object_ptr {
|
||||||
|
|
|
@ -524,6 +524,17 @@ inline void AddRandomSeed(bytes::const_span data) {
|
||||||
RAND_seed(data.data(), data.size());
|
RAND_seed(data.data(), data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>>
|
||||||
|
[[nodiscard]] inline T RandomValue() {
|
||||||
|
unsigned char buffer[sizeof(T)];
|
||||||
|
if (!RAND_bytes(buffer, sizeof(T))) {
|
||||||
|
Unexpected("Could not generate random bytes!");
|
||||||
|
}
|
||||||
|
auto result = T();
|
||||||
|
memcpy(&result, buffer, sizeof(T));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
inline bytes::vector Pbkdf2Sha512(
|
inline bytes::vector Pbkdf2Sha512(
|
||||||
bytes::const_span password,
|
bytes::const_span password,
|
||||||
bytes::const_span salt,
|
bytes::const_span salt,
|
||||||
|
|
|
@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QRegularExpression>
|
||||||
|
|
||||||
namespace qthelp {
|
namespace qthelp {
|
||||||
|
|
||||||
const QRegularExpression &RegExpDomain();
|
const QRegularExpression &RegExpDomain();
|
||||||
|
|
|
@ -108,8 +108,8 @@ void Timer::timerEvent(QTimerEvent *e) {
|
||||||
cancel();
|
cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_callback) {
|
if (const auto onstack = _callback) {
|
||||||
_callback();
|
onstack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtCore/QPointer>
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
@ -135,7 +136,7 @@ void BoxContent::onDraggingScrollDelta(int delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoxContent::onDraggingScrollTimer() {
|
void BoxContent::onDraggingScrollTimer() {
|
||||||
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(MaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(MaxScrollSpeed));
|
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(Ui::kMaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(Ui::kMaxScrollSpeed));
|
||||||
_scroll->scrollToY(_scroll->scrollTop() + delta);
|
_scroll->scrollToY(_scroll->scrollTop() + delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,7 +277,6 @@ AbstractBox::AbstractBox(
|
||||||
: LayerWidget(layer)
|
: LayerWidget(layer)
|
||||||
, _layer(layer)
|
, _layer(layer)
|
||||||
, _content(std::move(content)) {
|
, _content(std::move(content)) {
|
||||||
subscribe(Lang::Current().updated(), [=] { refreshLang(); });
|
|
||||||
_content->setParent(this);
|
_content->setParent(this);
|
||||||
_content->setDelegate(this);
|
_content->setDelegate(this);
|
||||||
|
|
||||||
|
@ -398,10 +398,6 @@ bool AbstractBox::closeByOutsideClick() const {
|
||||||
return _closeByOutsideClick;
|
return _closeByOutsideClick;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractBox::refreshLang() {
|
|
||||||
InvokeQueued(this, [this] { updateButtonsPositions(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AbstractBox::hasTitle() const {
|
bool AbstractBox::hasTitle() const {
|
||||||
return (_title != nullptr) || !_additionalTitle.current().isEmpty();
|
return (_title != nullptr) || !_additionalTitle.current().isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -464,7 +460,10 @@ QPointer<Ui::RoundButton> AbstractBox::addButton(
|
||||||
auto result = QPointer<Ui::RoundButton>(_buttons.back());
|
auto result = QPointer<Ui::RoundButton>(_buttons.back());
|
||||||
result->setClickedCallback(std::move(clickCallback));
|
result->setClickedCallback(std::move(clickCallback));
|
||||||
result->show();
|
result->show();
|
||||||
|
result->widthValue(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
updateButtonsPositions();
|
updateButtonsPositions();
|
||||||
|
}, result->lifetime());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +475,10 @@ QPointer<Ui::RoundButton> AbstractBox::addLeftButton(
|
||||||
auto result = QPointer<Ui::RoundButton>(_leftButton);
|
auto result = QPointer<Ui::RoundButton>(_leftButton);
|
||||||
result->setClickedCallback(std::move(clickCallback));
|
result->setClickedCallback(std::move(clickCallback));
|
||||||
result->show();
|
result->show();
|
||||||
|
result->widthValue(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
updateButtonsPositions();
|
updateButtonsPositions();
|
||||||
|
}, result->lifetime());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/unique_qptr.h"
|
#include "base/unique_qptr.h"
|
||||||
#include "base/flags.h"
|
#include "base/flags.h"
|
||||||
#include "ui/effects/animation_value.h"
|
#include "ui/effects/animation_value.h"
|
||||||
|
#include "ui/text/text_entity.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
|
class Painter;
|
||||||
|
|
||||||
namespace style {
|
namespace style {
|
||||||
struct RoundButton;
|
struct RoundButton;
|
||||||
struct IconButton;
|
struct IconButton;
|
||||||
|
@ -77,7 +80,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BoxContent : public Ui::RpWidget, protected base::Subscriber {
|
class BoxContent : public Ui::RpWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -270,10 +273,7 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AbstractBox
|
class AbstractBox : public Window::LayerWidget, public BoxContentDelegate {
|
||||||
: public Window::LayerWidget
|
|
||||||
, public BoxContentDelegate
|
|
||||||
, protected base::Subscriber {
|
|
||||||
public:
|
public:
|
||||||
AbstractBox(
|
AbstractBox(
|
||||||
not_null<Window::LayerStackWidget*> layer,
|
not_null<Window::LayerStackWidget*> layer,
|
||||||
|
@ -345,7 +345,6 @@ private:
|
||||||
|
|
||||||
void paintAdditionalTitle(Painter &p);
|
void paintAdditionalTitle(Painter &p);
|
||||||
void updateTitlePosition();
|
void updateTitlePosition();
|
||||||
void refreshLang();
|
|
||||||
|
|
||||||
[[nodiscard]] bool hasTitle() const;
|
[[nodiscard]] bool hasTitle() const;
|
||||||
[[nodiscard]] int titleHeight() const;
|
[[nodiscard]] int titleHeight() const;
|
||||||
|
|
|
@ -25,10 +25,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
|
#include "ui/special_fields.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
|
|
@ -139,7 +139,10 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SetupChannelBox : public BoxContent, public RPCSender {
|
class SetupChannelBox
|
||||||
|
: public BoxContent
|
||||||
|
, public RPCSender
|
||||||
|
, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
SetupChannelBox(
|
SetupChannelBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
|
@ -234,7 +237,10 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class RevokePublicLinkBox : public BoxContent, public RPCSender {
|
class RevokePublicLinkBox
|
||||||
|
: public BoxContent
|
||||||
|
, public RPCSender
|
||||||
|
, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
RevokePublicLinkBox(
|
RevokePublicLinkBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "boxes/background_preview_box.h"
|
#include "boxes/background_preview_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
|
|
@ -25,7 +25,8 @@ class Checkbox;
|
||||||
|
|
||||||
class BackgroundPreviewBox
|
class BackgroundPreviewBox
|
||||||
: public BoxContent
|
: public BoxContent
|
||||||
, private HistoryView::SimpleElementDelegate {
|
, private HistoryView::SimpleElementDelegate
|
||||||
|
, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
BackgroundPreviewBox(
|
BackgroundPreviewBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ui {
|
||||||
class IconButton;
|
class IconButton;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
class CalendarBox : public BoxContent {
|
class CalendarBox : public BoxContent, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
CalendarBox(
|
CalendarBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/special_fields.h"
|
||||||
#include "boxes/confirm_phone_box.h"
|
#include "boxes/confirm_phone_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
|
|
@ -254,8 +254,9 @@ void ConfirmBox::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
updateHover();
|
updateHover();
|
||||||
if (const auto activated = ClickHandler::unpressed()) {
|
if (const auto activated = ClickHandler::unpressed()) {
|
||||||
|
const auto guard = window();
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
App::activateClickHandler(activated, e->button());
|
ActivateClickHandler(guard, activated, e->button());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BoxContent::mouseReleaseEvent(e);
|
BoxContent::mouseReleaseEvent(e);
|
||||||
|
|
|
@ -95,7 +95,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaxInviteBox : public BoxContent {
|
class MaxInviteBox : public BoxContent, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
MaxInviteBox(QWidget*, not_null<ChannelData*> channel);
|
MaxInviteBox(QWidget*, not_null<ChannelData*> channel);
|
||||||
|
|
||||||
|
@ -201,7 +201,10 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfirmInviteBox : public BoxContent, public RPCSender {
|
class ConfirmInviteBox
|
||||||
|
: public BoxContent
|
||||||
|
, public RPCSender
|
||||||
|
, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
ConfirmInviteBox(
|
ConfirmInviteBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/edit_caption_box.h"
|
#include "boxes/edit_caption_box.h"
|
||||||
|
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "chat_helpers/emoji_suggestions_widget.h"
|
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
|
@ -21,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
@ -31,11 +33,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
#include "styles/style_history.h"
|
#include "styles/style_history.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
|
#include "ui/widgets/checkbox.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "ui/widgets/checkbox.h"
|
|
||||||
#include "confirm_box.h"
|
#include "confirm_box.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
@ -898,7 +901,7 @@ void EditCaptionBox::save() {
|
||||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||||
auto sending = TextWithEntities{
|
auto sending = TextWithEntities{
|
||||||
textWithTags.text,
|
textWithTags.text,
|
||||||
ConvertTextTagsToEntities(textWithTags.tags)
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
||||||
};
|
};
|
||||||
const auto prepareFlags = Ui::ItemTextOptions(
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
item->history(),
|
item->history(),
|
||||||
|
@ -906,9 +909,9 @@ void EditCaptionBox::save() {
|
||||||
TextUtilities::PrepareForSending(sending, prepareFlags);
|
TextUtilities::PrepareForSending(sending, prepareFlags);
|
||||||
TextUtilities::Trim(sending);
|
TextUtilities::Trim(sending);
|
||||||
|
|
||||||
const auto sentEntities = TextUtilities::EntitiesToMTP(
|
const auto sentEntities = Api::EntitiesToMTP(
|
||||||
sending.entities,
|
sending.entities,
|
||||||
TextUtilities::ConvertOption::SkipLocal);
|
Api::ConvertOption::SkipLocal);
|
||||||
if (!sentEntities.v.isEmpty()) {
|
if (!sentEntities.v.isEmpty()) {
|
||||||
flags |= MTPmessages_EditMessage::Flag::f_entities;
|
flags |= MTPmessages_EditMessage::Flag::f_entities;
|
||||||
}
|
}
|
||||||
|
@ -917,7 +920,7 @@ void EditCaptionBox::save() {
|
||||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||||
auto sending = TextWithEntities{
|
auto sending = TextWithEntities{
|
||||||
textWithTags.text,
|
textWithTags.text,
|
||||||
ConvertTextTagsToEntities(textWithTags.tags)
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
||||||
};
|
};
|
||||||
item->setText(sending);
|
item->setText(sending);
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,10 @@ namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
class EditCaptionBox : public BoxContent, public RPCSender {
|
class EditCaptionBox
|
||||||
|
: public BoxContent
|
||||||
|
, public RPCSender
|
||||||
|
, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
EditCaptionBox(
|
EditCaptionBox(
|
||||||
QWidget*,
|
QWidget*,
|
||||||
|
|
|
@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
|
|
||||||
class EditColorBox : public BoxContent {
|
class EditColorBox : public BoxContent, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
enum class Mode {
|
enum class Mode {
|
||||||
RGBA,
|
RGBA,
|
||||||
|
|
|
@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/padding_wrap.h"
|
#include "ui/wrap/padding_wrap.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "ui/special_fields.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include <rpl/flatten_latest.h>
|
#include <rpl/flatten_latest.h>
|
||||||
|
|
||||||
|
|
|
@ -441,7 +441,7 @@ void StickerSetBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
const auto index = stickerFromGlobalPos(e->globalPos());
|
const auto index = stickerFromGlobalPos(e->globalPos());
|
||||||
if (index >= 0 && index < _pack.size() && !isMasksSet()) {
|
if (index >= 0 && index < _pack.size() && !isMasksSet()) {
|
||||||
const auto sticker = _pack[index];
|
const auto sticker = _pack[index];
|
||||||
Core::App().postponeCall(crl::guard(App::main(), [=] {
|
Ui::PostponeCall(crl::guard(App::main(), [=] {
|
||||||
if (App::main()->onSendSticker(sticker)) {
|
if (App::main()->onSendSticker(sticker)) {
|
||||||
Ui::hideSettingsAndLayer();
|
Ui::hideSettingsAndLayer();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mtproto/sender.h"
|
#include "mtproto/sender.h"
|
||||||
#include "chat_helpers/stickers.h"
|
#include "chat_helpers/stickers.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/special_fields.h"
|
||||||
|
|
||||||
class ConfirmBox;
|
class ConfirmBox;
|
||||||
|
|
||||||
|
@ -32,7 +32,10 @@ namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
||||||
class StickersBox : public BoxContent, public RPCSender {
|
class StickersBox final
|
||||||
|
: public BoxContent
|
||||||
|
, public RPCSender
|
||||||
|
, private base::Subscriber {
|
||||||
public:
|
public:
|
||||||
enum class Section {
|
enum class Section {
|
||||||
Installed,
|
Installed,
|
||||||
|
|
|
@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/special_fields.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
|
|
@ -10,15 +10,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "calls/calls_emoji_fingerprint.h"
|
#include "calls/calls_emoji_fingerprint.h"
|
||||||
#include "styles/style_calls.h"
|
|
||||||
#include "styles/style_history.h"
|
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
|
#include "ui/platform/ui_platform_utility.h"
|
||||||
#include "ui/empty_userpic.h"
|
#include "ui/empty_userpic.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
@ -31,6 +31,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
#include "layout.h"
|
#include "layout.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
#include "styles/style_calls.h"
|
||||||
|
#include "styles/style_history.h"
|
||||||
|
|
||||||
#include <QtWidgets/QDesktopWidget>
|
#include <QtWidgets/QDesktopWidget>
|
||||||
#include <QtWidgets/QApplication>
|
#include <QtWidgets/QApplication>
|
||||||
|
@ -440,7 +442,7 @@ void Panel::initLayout() {
|
||||||
});
|
});
|
||||||
createDefaultCacheImage();
|
createDefaultCacheImage();
|
||||||
|
|
||||||
Platform::InitOnTopPanel(this);
|
Ui::Platform::InitOnTopPanel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panel::toggleOpacityAnimation(bool visible) {
|
void Panel::toggleOpacityAnimation(bool visible) {
|
||||||
|
@ -592,7 +594,7 @@ bool Panel::isGoodUserPhoto(PhotoData *photo) {
|
||||||
|
|
||||||
void Panel::initGeometry() {
|
void Panel::initGeometry() {
|
||||||
auto center = Core::App().getPointForCallPanelCenter();
|
auto center = Core::App().getPointForCallPanelCenter();
|
||||||
_useTransparency = Platform::TranslucentWindowsSupported(center);
|
_useTransparency = Ui::Platform::TranslucentWindowsSupported(center);
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||||
_padding = _useTransparency ? st::callShadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
|
_padding = _useTransparency ? st::callShadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
|
||||||
_contentTop = _padding.top() + st::callWidth;
|
_contentTop = _padding.top() + st::callWidth;
|
||||||
|
@ -704,7 +706,7 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
finishAnimating();
|
finishAnimating();
|
||||||
if (!_call || isHidden()) return;
|
if (!_call || isHidden()) return;
|
||||||
} else {
|
} else {
|
||||||
Platform::StartTranslucentPaint(p, e);
|
Ui::Platform::StartTranslucentPaint(p, e);
|
||||||
p.setOpacity(opacity);
|
p.setOpacity(opacity);
|
||||||
|
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
|
@ -717,7 +719,7 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_useTransparency) {
|
if (_useTransparency) {
|
||||||
Platform::StartTranslucentPaint(p, e);
|
Ui::Platform::StartTranslucentPaint(p, e);
|
||||||
p.drawPixmapLeft(0, 0, width(), _cache);
|
p.drawPixmapLeft(0, 0, width(), _cache);
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmapLeft(_padding.left(), _padding.top(), width(), _userPhoto);
|
p.drawPixmapLeft(_padding.left(), _padding.top(), width(), _userPhoto);
|
||||||
|
@ -864,9 +866,9 @@ void Panel::stateChanged(State state) {
|
||||||
if (windowHandle()) {
|
if (windowHandle()) {
|
||||||
// First stateChanged() is called before the first Platform::InitOnTopPanel(this).
|
// First stateChanged() is called before the first Platform::InitOnTopPanel(this).
|
||||||
if ((state == State::Starting) || (state == State::WaitingIncoming)) {
|
if ((state == State::Starting) || (state == State::WaitingIncoming)) {
|
||||||
Platform::ReInitOnTopPanel(this);
|
Ui::Platform::ReInitOnTopPanel(this);
|
||||||
} else {
|
} else {
|
||||||
Platform::DeInitOnTopPanel(this);
|
Ui::Platform::DeInitOnTopPanel(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state == State::Established) {
|
if (state == State::Established) {
|
||||||
|
|
|
@ -135,7 +135,7 @@ void BotKeyboard::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
if (ClickHandlerPtr activated = ClickHandler::unpressed()) {
|
if (ClickHandlerPtr activated = ClickHandler::unpressed()) {
|
||||||
App::activateClickHandler(activated, e->button());
|
ActivateClickHandler(window(), activated, e->button());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,6 +270,10 @@ QPoint BotKeyboard::tooltipPos() const {
|
||||||
return _lastMousePos;
|
return _lastMousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BotKeyboard::tooltipWindowActive() const {
|
||||||
|
return Ui::InFocusChain(window());
|
||||||
|
}
|
||||||
|
|
||||||
QString BotKeyboard::tooltipText() const {
|
QString BotKeyboard::tooltipText() const {
|
||||||
if (ClickHandlerPtr lnk = ClickHandler::getActive()) {
|
if (ClickHandlerPtr lnk = ClickHandler::getActive()) {
|
||||||
return lnk->tooltip();
|
return lnk->tooltip();
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
// AbstractTooltipShower interface
|
// AbstractTooltipShower interface
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
// ClickHandlerHost interface
|
// ClickHandlerHost interface
|
||||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||||
|
|
|
@ -769,6 +769,10 @@ QPoint EmojiListWidget::tooltipPos() const {
|
||||||
return _lastMousePos;
|
return _lastMousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EmojiListWidget::tooltipWindowActive() const {
|
||||||
|
return Ui::InFocusChain(window());
|
||||||
|
}
|
||||||
|
|
||||||
TabbedSelector::InnerFooter *EmojiListWidget::getFooter() const {
|
TabbedSelector::InnerFooter *EmojiListWidget::getFooter() const {
|
||||||
return _footer;
|
return _footer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
// Ui::AbstractTooltipShower interface.
|
// Ui::AbstractTooltipShower interface.
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
rpl::producer<EmojiPtr> chosen() const;
|
rpl::producer<EmojiPtr> chosen() const;
|
||||||
|
|
||||||
|
|
|
@ -356,7 +356,7 @@ void GifsListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
int row = _selected / MatrixRowShift, column = _selected % MatrixRowShift;
|
int row = _selected / MatrixRowShift, column = _selected % MatrixRowShift;
|
||||||
selectInlineResult(row, column);
|
selectInlineResult(row, column);
|
||||||
} else {
|
} else {
|
||||||
App::activateClickHandler(activated, e->button());
|
ActivateClickHandler(window(), activated, e->button());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,21 +39,12 @@ using EditLinkAction = Ui::InputField::EditLinkAction;
|
||||||
using EditLinkSelection = Ui::InputField::EditLinkSelection;
|
using EditLinkSelection = Ui::InputField::EditLinkSelection;
|
||||||
|
|
||||||
constexpr auto kParseLinksTimeout = crl::time(1000);
|
constexpr auto kParseLinksTimeout = crl::time(1000);
|
||||||
const auto kMentionTagStart = qstr("mention://user.");
|
|
||||||
|
|
||||||
bool IsMentionLink(const QString &link) {
|
|
||||||
return link.startsWith(kMentionTagStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For mention tags save and validate userId, ignore tags for different userId.
|
// For mention tags save and validate userId, ignore tags for different userId.
|
||||||
class FieldTagMimeProcessor : public Ui::InputField::TagMimeProcessor {
|
class FieldTagMimeProcessor : public Ui::InputField::TagMimeProcessor {
|
||||||
public:
|
public:
|
||||||
QString mimeTagFromTag(const QString &tagId) override {
|
|
||||||
return ConvertTagToMimeTag(tagId);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString tagFromMimeTag(const QString &mimeTag) override {
|
QString tagFromMimeTag(const QString &mimeTag) override {
|
||||||
if (IsMentionLink(mimeTag)) {
|
if (TextUtilities::IsMentionLink(mimeTag)) {
|
||||||
auto match = QRegularExpression(":(\\d+)$").match(mimeTag);
|
auto match = QRegularExpression(":(\\d+)$").match(mimeTag);
|
||||||
if (!match.hasMatch()
|
if (!match.hasMatch()
|
||||||
|| match.capturedRef(1).toInt() != Auth().userId()) {
|
|| match.capturedRef(1).toInt() != Auth().userId()) {
|
||||||
|
@ -216,135 +207,20 @@ TextWithEntities StripSupportHashtag(TextWithEntities &&text) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
QString ConvertTagToMimeTag(const QString &tagId) {
|
|
||||||
if (IsMentionLink(tagId)) {
|
|
||||||
return tagId + ':' + QString::number(Auth().userId());
|
|
||||||
}
|
|
||||||
return tagId;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString PrepareMentionTag(not_null<UserData*> user) {
|
QString PrepareMentionTag(not_null<UserData*> user) {
|
||||||
return kMentionTagStart
|
return TextUtilities::kMentionTagStart
|
||||||
+ QString::number(user->bareId())
|
+ QString::number(user->bareId())
|
||||||
+ '.'
|
+ '.'
|
||||||
+ QString::number(user->accessHash());
|
+ QString::number(user->accessHash());
|
||||||
}
|
}
|
||||||
|
|
||||||
EntitiesInText ConvertTextTagsToEntities(const TextWithTags::Tags &tags) {
|
|
||||||
EntitiesInText result;
|
|
||||||
if (tags.isEmpty()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.reserve(tags.size());
|
|
||||||
for (const auto &tag : tags) {
|
|
||||||
const auto push = [&](
|
|
||||||
EntityType type,
|
|
||||||
const QString &data = QString()) {
|
|
||||||
result.push_back(
|
|
||||||
EntityInText(type, tag.offset, tag.length, data));
|
|
||||||
};
|
|
||||||
if (IsMentionLink(tag.id)) {
|
|
||||||
if (auto match = qthelp::regex_match("^(\\d+\\.\\d+)(/|$)", tag.id.midRef(kMentionTagStart.size()))) {
|
|
||||||
push(EntityType::MentionName, match->captured(1));
|
|
||||||
}
|
|
||||||
} else if (tag.id == Ui::InputField::kTagBold) {
|
|
||||||
push(EntityType::Bold);
|
|
||||||
} else if (tag.id == Ui::InputField::kTagItalic) {
|
|
||||||
push(EntityType::Italic);
|
|
||||||
} else if (tag.id == Ui::InputField::kTagUnderline) {
|
|
||||||
push(EntityType::Underline);
|
|
||||||
} else if (tag.id == Ui::InputField::kTagStrikeOut) {
|
|
||||||
push(EntityType::StrikeOut);
|
|
||||||
} else if (tag.id == Ui::InputField::kTagCode) {
|
|
||||||
push(EntityType::Code);
|
|
||||||
} else if (tag.id == Ui::InputField::kTagPre) { // #TODO entities
|
|
||||||
push(EntityType::Pre);
|
|
||||||
} else /*if (ValidateUrl(tag.id)) */{ // We validate when we insert.
|
|
||||||
push(EntityType::CustomUrl, tag.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextWithTags::Tags ConvertEntitiesToTextTags(const EntitiesInText &entities) {
|
|
||||||
TextWithTags::Tags result;
|
|
||||||
if (entities.isEmpty()) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.reserve(entities.size());
|
|
||||||
for (const auto &entity : entities) {
|
|
||||||
const auto push = [&](const QString &tag) {
|
|
||||||
result.push_back({ entity.offset(), entity.length(), tag });
|
|
||||||
};
|
|
||||||
switch (entity.type()) {
|
|
||||||
case EntityType::MentionName: {
|
|
||||||
auto match = QRegularExpression(R"(^(\d+\.\d+)$)").match(entity.data());
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
push(kMentionTagStart + entity.data());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case EntityType::CustomUrl: {
|
|
||||||
const auto url = entity.data();
|
|
||||||
if (Ui::InputField::IsValidMarkdownLink(url)
|
|
||||||
&& !IsMentionLink(url)) {
|
|
||||||
push(url);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case EntityType::Bold: push(Ui::InputField::kTagBold); break;
|
|
||||||
case EntityType::Italic: push(Ui::InputField::kTagItalic); break;
|
|
||||||
case EntityType::Underline:
|
|
||||||
push(Ui::InputField::kTagUnderline);
|
|
||||||
break;
|
|
||||||
case EntityType::StrikeOut:
|
|
||||||
push(Ui::InputField::kTagStrikeOut);
|
|
||||||
break;
|
|
||||||
case EntityType::Code: push(Ui::InputField::kTagCode); break; // #TODO entities
|
|
||||||
case EntityType::Pre: push(Ui::InputField::kTagPre); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<QMimeData> MimeDataFromText(
|
|
||||||
const TextForMimeData &text) {
|
|
||||||
if (text.empty()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = std::make_unique<QMimeData>();
|
|
||||||
result->setText(text.expanded);
|
|
||||||
auto tags = ConvertEntitiesToTextTags(text.rich.entities);
|
|
||||||
if (!tags.isEmpty()) {
|
|
||||||
for (auto &tag : tags) {
|
|
||||||
tag.id = ConvertTagToMimeTag(tag.id);
|
|
||||||
}
|
|
||||||
result->setData(
|
|
||||||
TextUtilities::TagsTextMimeType(),
|
|
||||||
text.rich.text.toUtf8());
|
|
||||||
result->setData(
|
|
||||||
TextUtilities::TagsMimeType(),
|
|
||||||
TextUtilities::SerializeTags(tags));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetClipboardText(
|
|
||||||
const TextForMimeData &text,
|
|
||||||
QClipboard::Mode mode) {
|
|
||||||
if (auto data = MimeDataFromText(text)) {
|
|
||||||
QGuiApplication::clipboard()->setMimeData(data.release(), mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TextWithTags PrepareEditText(not_null<HistoryItem*> item) {
|
TextWithTags PrepareEditText(not_null<HistoryItem*> item) {
|
||||||
const auto original = item->history()->session().supportMode()
|
const auto original = item->history()->session().supportMode()
|
||||||
? StripSupportHashtag(item->originalText())
|
? StripSupportHashtag(item->originalText())
|
||||||
: item->originalText();
|
: item->originalText();
|
||||||
return TextWithTags{
|
return TextWithTags{
|
||||||
original.text,
|
original.text,
|
||||||
ConvertEntitiesToTextTags(original.entities)
|
TextUtilities::ConvertEntitiesToTextTags(original.entities)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +239,7 @@ Fn<bool(
|
||||||
EditLinkAction action) {
|
EditLinkAction action) {
|
||||||
if (action == EditLinkAction::Check) {
|
if (action == EditLinkAction::Check) {
|
||||||
return Ui::InputField::IsValidMarkdownLink(link)
|
return Ui::InputField::IsValidMarkdownLink(link)
|
||||||
&& !IsMentionLink(link);
|
&& !TextUtilities::IsMentionLink(link);
|
||||||
}
|
}
|
||||||
Ui::show(Box<EditLinkBox>(session, text, link, [=](
|
Ui::show(Box<EditLinkBox>(session, text, link, [=](
|
||||||
const QString &text,
|
const QString &text,
|
||||||
|
@ -617,7 +493,7 @@ void MessageLinksParser::parse() {
|
||||||
Expects(tag != tagsEnd);
|
Expects(tag != tagsEnd);
|
||||||
|
|
||||||
if (Ui::InputField::IsValidMarkdownLink(tag->id)
|
if (Ui::InputField::IsValidMarkdownLink(tag->id)
|
||||||
&& !IsMentionLink(tag->id)) {
|
&& !TextUtilities::IsMentionLink(tag->id)) {
|
||||||
ranges.push_back({ tag->offset, tag->length, tag->id });
|
ranges.push_back({ tag->offset, tag->length, tag->id });
|
||||||
}
|
}
|
||||||
++tag;
|
++tag;
|
||||||
|
|
|
@ -21,16 +21,7 @@ namespace Window {
|
||||||
class SessionController;
|
class SessionController;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
QString ConvertTagToMimeTag(const QString &tagId);
|
|
||||||
QString PrepareMentionTag(not_null<UserData*> user);
|
QString PrepareMentionTag(not_null<UserData*> user);
|
||||||
|
|
||||||
EntitiesInText ConvertTextTagsToEntities(const TextWithTags::Tags &tags);
|
|
||||||
TextWithTags::Tags ConvertEntitiesToTextTags(
|
|
||||||
const EntitiesInText &entities);
|
|
||||||
std::unique_ptr<QMimeData> MimeDataFromText(const TextForMimeData &text);
|
|
||||||
void SetClipboardText(
|
|
||||||
const TextForMimeData &text,
|
|
||||||
QClipboard::Mode mode = QClipboard::Clipboard);
|
|
||||||
TextWithTags PrepareEditText(not_null<HistoryItem*> item);
|
TextWithTags PrepareEditText(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
Fn<bool(
|
Fn<bool(
|
||||||
|
|
|
@ -323,8 +323,7 @@ void TabbedPanel::startShowAnimation() {
|
||||||
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, Ui::PanelAnimation::Origin::BottomRight);
|
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, Ui::PanelAnimation::Origin::BottomRight);
|
||||||
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
||||||
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
||||||
auto corners = App::cornersMask(ImageRoundRadius::Small);
|
_showAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||||
_showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]);
|
|
||||||
_showAnimation->start();
|
_showAnimation->start();
|
||||||
}
|
}
|
||||||
hideChildren();
|
hideChildren();
|
||||||
|
|
|
@ -813,8 +813,7 @@ void TabbedSelector::switchTab() {
|
||||||
_slideAnimation = std::make_unique<SlideAnimation>();
|
_slideAnimation = std::make_unique<SlideAnimation>();
|
||||||
auto slidingRect = QRect(0, _scroll->y() * cIntRetinaFactor(), width() * cIntRetinaFactor(), (height() - _scroll->y()) * cIntRetinaFactor());
|
auto slidingRect = QRect(0, _scroll->y() * cIntRetinaFactor(), width() * cIntRetinaFactor(), (height() - _scroll->y()) * cIntRetinaFactor());
|
||||||
_slideAnimation->setFinalImages(direction, std::move(wasCache), std::move(nowCache), slidingRect, wasSectionIcons);
|
_slideAnimation->setFinalImages(direction, std::move(wasCache), std::move(nowCache), slidingRect, wasSectionIcons);
|
||||||
auto corners = App::cornersMask(ImageRoundRadius::Small);
|
_slideAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||||
_slideAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]);
|
|
||||||
_slideAnimation->start();
|
_slideAnimation->start();
|
||||||
|
|
||||||
hideForSliding();
|
hideForSliding();
|
||||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "codegen/style/generator.h"
|
#include "codegen/style/generator.h"
|
||||||
|
|
||||||
|
#include "base/crc32hash.h"
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -33,54 +35,6 @@ const auto kMustBeContrast = std::map<QString, QString>{
|
||||||
{ "windowBoldFg", "windowBg" },
|
{ "windowBoldFg", "windowBg" },
|
||||||
};
|
};
|
||||||
|
|
||||||
// crc32 hash, taken somewhere from the internet
|
|
||||||
|
|
||||||
class Crc32Table {
|
|
||||||
public:
|
|
||||||
Crc32Table() {
|
|
||||||
quint32 poly = 0x04c11db7;
|
|
||||||
for (auto i = 0; i != 256; ++i) {
|
|
||||||
_data[i] = reflect(i, 8) << 24;
|
|
||||||
for (auto j = 0; j != 8; ++j) {
|
|
||||||
_data[i] = (_data[i] << 1) ^ (_data[i] & (1 << 31) ? poly : 0);
|
|
||||||
}
|
|
||||||
_data[i] = reflect(_data[i], 32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline quint32 operator[](int index) const {
|
|
||||||
return _data[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
quint32 reflect(quint32 val, char ch) {
|
|
||||||
quint32 result = 0;
|
|
||||||
for (int i = 1; i < (ch + 1); ++i) {
|
|
||||||
if (val & 1) {
|
|
||||||
result |= 1 << (ch - i);
|
|
||||||
}
|
|
||||||
val >>= 1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint32 _data[256];
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
qint32 hashCrc32(const void *data, int len) {
|
|
||||||
static Crc32Table table;
|
|
||||||
|
|
||||||
const uchar *buffer = static_cast<const uchar *>(data);
|
|
||||||
|
|
||||||
quint32 crc = 0xffffffff;
|
|
||||||
for (int i = 0; i != len; ++i) {
|
|
||||||
crc = (crc >> 8) ^ table[(crc & 0xFF) ^ buffer[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<qint32>(crc ^ 0xffffffff);
|
|
||||||
}
|
|
||||||
|
|
||||||
char hexChar(uchar ch) {
|
char hexChar(uchar ch) {
|
||||||
if (ch < 10) {
|
if (ch < 10) {
|
||||||
return '0' + ch;
|
return '0' + ch;
|
||||||
|
@ -844,7 +798,7 @@ void palette::finalize() {\n\
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto count = indexInPalette;
|
auto count = indexInPalette;
|
||||||
auto checksum = hashCrc32(checksumString.constData(), checksumString.size());
|
auto checksum = base::crc32(checksumString.constData(), checksumString.size());
|
||||||
|
|
||||||
source_->stream() << "\n\n";
|
source_->stream() << "\n\n";
|
||||||
for (const auto &[over, under] : kMustBeContrast) {
|
for (const auto &[over, under] : kMustBeContrast) {
|
||||||
|
|
|
@ -22,11 +22,6 @@ enum {
|
||||||
MaxPhoneCodeLength = 4, // max length of country phone code
|
MaxPhoneCodeLength = 4, // max length of country phone code
|
||||||
MaxPhoneTailLength = 32, // rest of the phone number, without country code (seen 12 at least), need more for service numbers
|
MaxPhoneTailLength = 32, // rest of the phone number, without country code (seen 12 at least), need more for service numbers
|
||||||
|
|
||||||
MaxScrollSpeed = 37, // 37px per 15ms while select-by-drag
|
|
||||||
FingerAccuracyThreshold = 3, // touch flick ignore 3px
|
|
||||||
MaxScrollAccelerated = 4000, // 4000px per second
|
|
||||||
MaxScrollFlick = 2500, // 2500px per second
|
|
||||||
|
|
||||||
LocalEncryptIterCount = 4000, // key derivation iteration count
|
LocalEncryptIterCount = 4000, // key derivation iteration count
|
||||||
LocalEncryptNoPwdIterCount = 4, // key derivation iteration count without pwd (not secure anyway)
|
LocalEncryptNoPwdIterCount = 4, // key derivation iteration count without pwd (not secure anyway)
|
||||||
LocalEncryptSaltSize = 32, // 256 bit
|
LocalEncryptSaltSize = 32, // 256 bit
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/sandbox.h"
|
#include "core/sandbox.h"
|
||||||
#include "core/local_url_handlers.h"
|
#include "core/local_url_handlers.h"
|
||||||
#include "core/launcher.h"
|
#include "core/launcher.h"
|
||||||
|
#include "core/core_ui_integration.h"
|
||||||
#include "chat_helpers/emoji_keywords.h"
|
#include "chat_helpers/emoji_keywords.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "platform/platform_specific.h"
|
#include "platform/platform_specific.h"
|
||||||
|
@ -80,6 +81,7 @@ Application *Application::Instance = nullptr;
|
||||||
|
|
||||||
struct Application::Private {
|
struct Application::Private {
|
||||||
base::Timer quitTimer;
|
base::Timer quitTimer;
|
||||||
|
UiIntegration uiIntegration;
|
||||||
};
|
};
|
||||||
|
|
||||||
Application::Application(not_null<Launcher*> launcher)
|
Application::Application(not_null<Launcher*> launcher)
|
||||||
|
@ -98,6 +100,8 @@ Application::Application(not_null<Launcher*> launcher)
|
||||||
Expects(!_logo.isNull());
|
Expects(!_logo.isNull());
|
||||||
Expects(!_logoNoMargin.isNull());
|
Expects(!_logoNoMargin.isNull());
|
||||||
|
|
||||||
|
Ui::Integration::Set(&_private->uiIntegration);
|
||||||
|
|
||||||
activeAccount().sessionChanges(
|
activeAccount().sessionChanges(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
if (_mediaView) {
|
if (_mediaView) {
|
||||||
|
@ -778,25 +782,6 @@ void Application::refreshGlobalProxy() {
|
||||||
Sandbox::Instance().refreshGlobalProxy();
|
Sandbox::Instance().refreshGlobalProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::activateWindowDelayed(not_null<QWidget*> widget) {
|
|
||||||
Sandbox::Instance().activateWindowDelayed(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::pauseDelayedWindowActivations() {
|
|
||||||
Sandbox::Instance().pauseDelayedWindowActivations();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::resumeDelayedWindowActivations() {
|
|
||||||
Sandbox::Instance().resumeDelayedWindowActivations();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::preventWindowActivation() {
|
|
||||||
pauseDelayedWindowActivations();
|
|
||||||
postponeCall([=] {
|
|
||||||
resumeDelayedWindowActivations();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::QuitAttempt() {
|
void Application::QuitAttempt() {
|
||||||
auto prevents = false;
|
auto prevents = false;
|
||||||
if (IsAppLaunched()
|
if (IsAppLaunched()
|
||||||
|
@ -871,19 +856,3 @@ Application &App() {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
|
|
||||||
void PostponeCall(FnMut<void()> &&callable) {
|
|
||||||
Core::App().postponeCall(std::move(callable));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterLeaveSubscription(not_null<QWidget*> widget) {
|
|
||||||
Core::App().registerLeaveSubscription(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnregisterLeaveSubscription(not_null<QWidget*> widget) {
|
|
||||||
Core::App().unregisterLeaveSubscription(widget);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Ui
|
|
||||||
|
|
|
@ -205,10 +205,6 @@ public:
|
||||||
// Sandbox interface.
|
// Sandbox interface.
|
||||||
void postponeCall(FnMut<void()> &&callable);
|
void postponeCall(FnMut<void()> &&callable);
|
||||||
void refreshGlobalProxy();
|
void refreshGlobalProxy();
|
||||||
void activateWindowDelayed(not_null<QWidget*> widget);
|
|
||||||
void pauseDelayedWindowActivations();
|
|
||||||
void resumeDelayedWindowActivations();
|
|
||||||
void preventWindowActivation();
|
|
||||||
|
|
||||||
void quitPreventFinished();
|
void quitPreventFinished();
|
||||||
|
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of Telegram Desktop,
|
|
||||||
the official desktop application for the Telegram messaging service.
|
|
||||||
|
|
||||||
For license and copyright information please follow this link:
|
|
||||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
||||||
*/
|
|
||||||
#include "core/click_handler.h"
|
|
||||||
|
|
||||||
ClickHandlerHost::~ClickHandlerHost() {
|
|
||||||
ClickHandler::hostDestroyed(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
NeverFreedPointer<ClickHandlerPtr> ClickHandler::_active;
|
|
||||||
NeverFreedPointer<ClickHandlerPtr> ClickHandler::_pressed;
|
|
||||||
ClickHandlerHost *ClickHandler::_activeHost = nullptr;
|
|
||||||
ClickHandlerHost *ClickHandler::_pressedHost = nullptr;
|
|
||||||
|
|
||||||
bool ClickHandler::setActive(const ClickHandlerPtr &p, ClickHandlerHost *host) {
|
|
||||||
if ((_active && (*_active == p)) || (!_active && !p)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// emit clickHandlerActiveChanged only when there is no
|
|
||||||
// other pressed click handler currently, if there is
|
|
||||||
// this method will be called when it is unpressed
|
|
||||||
if (_active && *_active) {
|
|
||||||
const auto emitClickHandlerActiveChanged = false
|
|
||||||
|| !_pressed
|
|
||||||
|| !*_pressed
|
|
||||||
|| (*_pressed == *_active);
|
|
||||||
const auto wasactive = base::take(*_active);
|
|
||||||
if (_activeHost) {
|
|
||||||
if (emitClickHandlerActiveChanged) {
|
|
||||||
_activeHost->clickHandlerActiveChanged(wasactive, false);
|
|
||||||
}
|
|
||||||
_activeHost = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (p) {
|
|
||||||
_active.createIfNull();
|
|
||||||
*_active = p;
|
|
||||||
if ((_activeHost = host)) {
|
|
||||||
bool emitClickHandlerActiveChanged = (!_pressed || !*_pressed || *_pressed == *_active);
|
|
||||||
if (emitClickHandlerActiveChanged) {
|
|
||||||
_activeHost->clickHandlerActiveChanged(*_active, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ClickHandler::getTextEntity() const -> TextEntity {
|
|
||||||
return { EntityType::Invalid };
|
|
||||||
}
|
|
|
@ -10,17 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/local_url_handlers.h"
|
#include "core/local_url_handlers.h"
|
||||||
#include "core/file_utilities.h"
|
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "platform/platform_specific.h"
|
|
||||||
#include "history/view/history_view_element.h"
|
|
||||||
#include "history/history_item.h"
|
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "base/qthelp_regex.h"
|
#include "base/qthelp_regex.h"
|
||||||
#include "base/qthelp_url.h"
|
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "history/view/history_view_element.h"
|
||||||
|
#include "history/history_item.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
|
@ -38,63 +34,6 @@ bool UrlRequiresConfirmation(const QUrl &url) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
UrlClickHandler::UrlClickHandler(const QString &url, bool fullDisplayed)
|
|
||||||
: TextClickHandler(fullDisplayed)
|
|
||||||
, _originalUrl(url) {
|
|
||||||
if (isEmail()) {
|
|
||||||
_readable = _originalUrl;
|
|
||||||
} else {
|
|
||||||
const auto original = QUrl(_originalUrl);
|
|
||||||
const auto good = QUrl(original.isValid()
|
|
||||||
? original.toEncoded()
|
|
||||||
: QString());
|
|
||||||
_readable = good.isValid() ? good.toDisplayString() : _originalUrl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString UrlClickHandler::copyToClipboardContextItemText() const {
|
|
||||||
return isEmail()
|
|
||||||
? tr::lng_context_copy_email(tr::now)
|
|
||||||
: tr::lng_context_copy_link(tr::now);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString UrlClickHandler::url() const {
|
|
||||||
if (isEmail()) {
|
|
||||||
return _originalUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl u(_originalUrl), good(u.isValid() ? u.toEncoded() : QString());
|
|
||||||
QString result(good.isValid() ? QString::fromUtf8(good.toEncoded()) : _originalUrl);
|
|
||||||
|
|
||||||
if (!result.isEmpty() && !QRegularExpression(qsl("^[a-zA-Z]+:")).match(result).hasMatch()) { // no protocol
|
|
||||||
return qsl("http://") + result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UrlClickHandler::Open(QString url, QVariant context) {
|
|
||||||
url = Core::TryConvertUrlToLocal(url);
|
|
||||||
if (Core::InternalPassportLink(url)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ui::Tooltip::Hide();
|
|
||||||
if (isEmail(url)) {
|
|
||||||
File::OpenEmailLink(url);
|
|
||||||
} else if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
|
|
||||||
Core::App().openLocalUrl(url, context);
|
|
||||||
} else if (!url.isEmpty()) {
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto UrlClickHandler::getTextEntity() const -> TextEntity {
|
|
||||||
const auto type = isEmail(_originalUrl)
|
|
||||||
? EntityType::Email
|
|
||||||
: EntityType::Url;
|
|
||||||
return { type, _originalUrl };
|
|
||||||
}
|
|
||||||
|
|
||||||
void HiddenUrlClickHandler::Open(QString url, QVariant context) {
|
void HiddenUrlClickHandler::Open(QString url, QVariant context) {
|
||||||
url = Core::TryConvertUrlToLocal(url);
|
url = Core::TryConvertUrlToLocal(url);
|
||||||
if (Core::InternalPassportLink(url)) {
|
if (Core::InternalPassportLink(url)) {
|
||||||
|
|
|
@ -7,74 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/click_handler.h"
|
#include "ui/basic_click_handlers.h"
|
||||||
|
|
||||||
class TextClickHandler : public ClickHandler {
|
|
||||||
public:
|
|
||||||
TextClickHandler(bool fullDisplayed = true)
|
|
||||||
: _fullDisplayed(fullDisplayed) {
|
|
||||||
}
|
|
||||||
|
|
||||||
QString copyToClipboardText() const override {
|
|
||||||
return url();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString tooltip() const override {
|
|
||||||
return _fullDisplayed ? QString() : readable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFullDisplayed(bool full) {
|
|
||||||
_fullDisplayed = full;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual QString url() const = 0;
|
|
||||||
virtual QString readable() const {
|
|
||||||
return url();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _fullDisplayed;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class UrlClickHandler : public TextClickHandler {
|
|
||||||
public:
|
|
||||||
UrlClickHandler(const QString &url, bool fullDisplayed = true);
|
|
||||||
|
|
||||||
QString copyToClipboardContextItemText() const override;
|
|
||||||
|
|
||||||
QString dragText() const override {
|
|
||||||
return url();
|
|
||||||
}
|
|
||||||
|
|
||||||
TextEntity getTextEntity() const override;
|
|
||||||
|
|
||||||
static void Open(QString url, QVariant context = {});
|
|
||||||
void onClick(ClickContext context) const override {
|
|
||||||
const auto button = context.button;
|
|
||||||
if (button == Qt::LeftButton || button == Qt::MiddleButton) {
|
|
||||||
Open(url(), context.other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QString url() const override;
|
|
||||||
QString readable() const override {
|
|
||||||
return _readable;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static bool isEmail(const QString &url) {
|
|
||||||
int at = url.indexOf('@'), slash = url.indexOf('/');
|
|
||||||
return ((at > 0) && (slash < 0 || slash > at));
|
|
||||||
}
|
|
||||||
bool isEmail() const {
|
|
||||||
return isEmail(_originalUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
QString _originalUrl, _readable;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class HiddenUrlClickHandler : public UrlClickHandler {
|
class HiddenUrlClickHandler : public UrlClickHandler {
|
||||||
public:
|
public:
|
||||||
|
@ -98,6 +31,7 @@ public:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UserData;
|
||||||
class BotGameUrlClickHandler : public UrlClickHandler {
|
class BotGameUrlClickHandler : public UrlClickHandler {
|
||||||
public:
|
public:
|
||||||
BotGameUrlClickHandler(UserData *bot, QString url)
|
BotGameUrlClickHandler(UserData *bot, QString url)
|
||||||
|
@ -208,7 +142,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class PeerData;
|
class PeerData;
|
||||||
class UserData;
|
|
||||||
class BotCommandClickHandler : public TextClickHandler {
|
class BotCommandClickHandler : public TextClickHandler {
|
||||||
public:
|
public:
|
||||||
BotCommandClickHandler(const QString &cmd) : _cmd(cmd) {
|
BotCommandClickHandler(const QString &cmd) : _cmd(cmd) {
|
||||||
|
|
217
Telegram/SourceFiles/core/core_ui_integration.cpp
Normal file
217
Telegram/SourceFiles/core/core_ui_integration.cpp
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "core/core_ui_integration.h"
|
||||||
|
|
||||||
|
#include "core/local_url_handlers.h"
|
||||||
|
#include "core/file_utilities.h"
|
||||||
|
#include "core/application.h"
|
||||||
|
#include "core/sandbox.h"
|
||||||
|
#include "core/click_handler_types.h"
|
||||||
|
#include "ui/basic_click_handlers.h"
|
||||||
|
#include "ui/emoji_config.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "platform/platform_specific.h"
|
||||||
|
#include "main/main_account.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "mainwindow.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
void UiIntegration::postponeCall(FnMut<void()> &&callable) {
|
||||||
|
Sandbox::Instance().postponeCall(std::move(callable));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::registerLeaveSubscription(not_null<QWidget*> widget) {
|
||||||
|
Core::App().registerLeaveSubscription(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::unregisterLeaveSubscription(not_null<QWidget*> widget) {
|
||||||
|
Core::App().unregisterLeaveSubscription(widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::writeLogEntry(const QString &entry) {
|
||||||
|
Logs::writeMain(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::emojiCacheFolder() {
|
||||||
|
return cWorkingDir() + "tdata/emoji";
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::textActionsUpdated() {
|
||||||
|
if (const auto window = App::wnd()) {
|
||||||
|
window->updateGlobalMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UiIntegration::activationFromTopPanel() {
|
||||||
|
Platform::IgnoreApplicationActivationRightNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ClickHandler> UiIntegration::createLinkHandler(
|
||||||
|
EntityType type,
|
||||||
|
const QString &text,
|
||||||
|
const QString &data,
|
||||||
|
const TextParseOptions &options) {
|
||||||
|
switch (type) {
|
||||||
|
case EntityType::CustomUrl:
|
||||||
|
return !data.isEmpty()
|
||||||
|
? std::make_shared<HiddenUrlClickHandler>(data)
|
||||||
|
: nullptr;
|
||||||
|
|
||||||
|
case EntityType::BotCommand:
|
||||||
|
return std::make_shared<BotCommandClickHandler>(data);
|
||||||
|
|
||||||
|
case EntityType::Hashtag:
|
||||||
|
if (options.flags & TextTwitterMentions) {
|
||||||
|
return std::make_shared<UrlClickHandler>(
|
||||||
|
(qsl("https://twitter.com/hashtag/")
|
||||||
|
+ data.mid(1)
|
||||||
|
+ qsl("?src=hash")),
|
||||||
|
true);
|
||||||
|
} else if (options.flags & TextInstagramMentions) {
|
||||||
|
return std::make_shared<UrlClickHandler>(
|
||||||
|
(qsl("https://instagram.com/explore/tags/")
|
||||||
|
+ data.mid(1)
|
||||||
|
+ '/'),
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
return std::make_shared<HashtagClickHandler>(data);
|
||||||
|
|
||||||
|
case EntityType::Cashtag:
|
||||||
|
return std::make_shared<CashtagClickHandler>(data);
|
||||||
|
|
||||||
|
case EntityType::Mention:
|
||||||
|
if (options.flags & TextTwitterMentions) {
|
||||||
|
return std::make_shared<UrlClickHandler>(
|
||||||
|
qsl("https://twitter.com/") + data.mid(1),
|
||||||
|
true);
|
||||||
|
} else if (options.flags & TextInstagramMentions) {
|
||||||
|
return std::make_shared<UrlClickHandler>(
|
||||||
|
qsl("https://instagram.com/") + data.mid(1) + '/',
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
return std::make_shared<MentionClickHandler>(data);
|
||||||
|
|
||||||
|
case EntityType::MentionName: {
|
||||||
|
auto fields = TextUtilities::MentionNameDataToFields(data);
|
||||||
|
if (fields.userId) {
|
||||||
|
return std::make_shared<MentionNameClickHandler>(
|
||||||
|
text,
|
||||||
|
fields.userId,
|
||||||
|
fields.accessHash);
|
||||||
|
} else {
|
||||||
|
LOG(("Bad mention name: %1").arg(data));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UiIntegration::handleUrlClick(
|
||||||
|
const QString &url,
|
||||||
|
const QVariant &context) {
|
||||||
|
auto local = Core::TryConvertUrlToLocal(url);
|
||||||
|
if (Core::InternalPassportLink(local)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UrlClickHandler::IsEmail(url)) {
|
||||||
|
File::OpenEmailLink(url);
|
||||||
|
return true;
|
||||||
|
} else if (url.startsWith(qstr("tg://"), Qt::CaseInsensitive)) {
|
||||||
|
Core::App().openLocalUrl(url, context);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<> UiIntegration::forcePopupMenuHideRequests() {
|
||||||
|
return rpl::merge(
|
||||||
|
Core::App().passcodeLockChanges(),
|
||||||
|
Core::App().termsLockChanges()
|
||||||
|
) | rpl::map([] { return rpl::empty_value(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::convertTagToMimeTag(const QString &tagId) {
|
||||||
|
if (TextUtilities::IsMentionLink(tagId)) {
|
||||||
|
const auto &account = Core::App().activeAccount();
|
||||||
|
if (account.sessionExists()) {
|
||||||
|
return tagId + ':' + QString::number(account.session().userId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tagId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Ui::Emoji::One *UiIntegration::defaultEmojiVariant(
|
||||||
|
const Ui::Emoji::One *emoji) {
|
||||||
|
if (!emoji || !emoji->hasVariants()) {
|
||||||
|
return emoji;
|
||||||
|
}
|
||||||
|
const auto nonColored = emoji->nonColoredId();
|
||||||
|
const auto it = cEmojiVariants().constFind(nonColored);
|
||||||
|
const auto result = (it != cEmojiVariants().cend())
|
||||||
|
? emoji->variant(it.value())
|
||||||
|
: emoji;
|
||||||
|
AddRecentEmoji(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseContextCopyText() {
|
||||||
|
return tr::lng_context_copy_text(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseContextCopyEmail() {
|
||||||
|
return tr::lng_context_copy_email(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseContextCopyLink() {
|
||||||
|
return tr::lng_context_copy_link(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseContextCopySelected() {
|
||||||
|
return tr::lng_context_copy_selected(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingTitle() {
|
||||||
|
return tr::lng_menu_formatting(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingLinkCreate() {
|
||||||
|
return tr::lng_menu_formatting_link_create(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingLinkEdit() {
|
||||||
|
return tr::lng_menu_formatting_link_edit(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingClear() {
|
||||||
|
return tr::lng_menu_formatting_clear(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingBold() {
|
||||||
|
return tr::lng_menu_formatting_bold(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingItalic() {
|
||||||
|
return tr::lng_menu_formatting_italic(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingUnderline() {
|
||||||
|
return tr::lng_menu_formatting_underline(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingStrikeOut() {
|
||||||
|
return tr::lng_menu_formatting_strike_out(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString UiIntegration::phraseFormattingMonospace() {
|
||||||
|
return tr::lng_menu_formatting_monospace(tr::now);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Core
|
55
Telegram/SourceFiles/core/core_ui_integration.h
Normal file
55
Telegram/SourceFiles/core/core_ui_integration.h
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ui/ui_integration.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
class UiIntegration : public Ui::Integration {
|
||||||
|
public:
|
||||||
|
void postponeCall(FnMut<void()> &&callable) override;
|
||||||
|
void registerLeaveSubscription(not_null<QWidget*> widget) override;
|
||||||
|
void unregisterLeaveSubscription(not_null<QWidget*> widget) override;
|
||||||
|
|
||||||
|
void writeLogEntry(const QString &entry) override;
|
||||||
|
QString emojiCacheFolder() override;
|
||||||
|
|
||||||
|
void textActionsUpdated() override;
|
||||||
|
void activationFromTopPanel() override;
|
||||||
|
|
||||||
|
std::shared_ptr<ClickHandler> createLinkHandler(
|
||||||
|
EntityType type,
|
||||||
|
const QString &text,
|
||||||
|
const QString &data,
|
||||||
|
const TextParseOptions &options) override;
|
||||||
|
bool handleUrlClick(
|
||||||
|
const QString &url,
|
||||||
|
const QVariant &context) override;
|
||||||
|
rpl::producer<> forcePopupMenuHideRequests() override;
|
||||||
|
QString convertTagToMimeTag(const QString &tagId) override;
|
||||||
|
const Ui::Emoji::One *defaultEmojiVariant(
|
||||||
|
const Ui::Emoji::One *emoji) override;
|
||||||
|
|
||||||
|
QString phraseContextCopyText() override;
|
||||||
|
QString phraseContextCopyEmail() override;
|
||||||
|
QString phraseContextCopyLink() override;
|
||||||
|
QString phraseContextCopySelected() override;
|
||||||
|
QString phraseFormattingTitle() override;
|
||||||
|
QString phraseFormattingLinkCreate() override;
|
||||||
|
QString phraseFormattingLinkEdit() override;
|
||||||
|
QString phraseFormattingClear() override;
|
||||||
|
QString phraseFormattingBold() override;
|
||||||
|
QString phraseFormattingItalic() override;
|
||||||
|
QString phraseFormattingUnderline() override;
|
||||||
|
QString phraseFormattingStrikeOut() override;
|
||||||
|
QString phraseFormattingMonospace() override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "platform/platform_file_utilities.h"
|
#include "platform/platform_file_utilities.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include "ui/delayed_activation.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include <QtWidgets/QFileDialog>
|
#include <QtWidgets/QFileDialog>
|
||||||
|
@ -26,7 +27,7 @@ bool filedialogGetSaveFile(
|
||||||
const QString &initialPath) {
|
const QString &initialPath) {
|
||||||
QStringList files;
|
QStringList files;
|
||||||
QByteArray remoteContent;
|
QByteArray remoteContent;
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
bool result = Platform::FileDialog::Get(
|
bool result = Platform::FileDialog::Get(
|
||||||
parent,
|
parent,
|
||||||
files,
|
files,
|
||||||
|
@ -119,7 +120,7 @@ namespace File {
|
||||||
|
|
||||||
void OpenEmailLink(const QString &email) {
|
void OpenEmailLink(const QString &email) {
|
||||||
crl::on_main([=] {
|
crl::on_main([=] {
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
Platform::File::UnsafeOpenEmailLink(email);
|
Platform::File::UnsafeOpenEmailLink(email);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -127,7 +128,7 @@ void OpenEmailLink(const QString &email) {
|
||||||
void OpenWith(const QString &filepath, QPoint menuPosition) {
|
void OpenWith(const QString &filepath, QPoint menuPosition) {
|
||||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||||
if (!Platform::File::UnsafeShowOpenWithDropdown(filepath, menuPosition)) {
|
if (!Platform::File::UnsafeShowOpenWithDropdown(filepath, menuPosition)) {
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
if (!Platform::File::UnsafeShowOpenWith(filepath)) {
|
if (!Platform::File::UnsafeShowOpenWith(filepath)) {
|
||||||
Platform::File::UnsafeLaunch(filepath);
|
Platform::File::UnsafeLaunch(filepath);
|
||||||
}
|
}
|
||||||
|
@ -137,14 +138,14 @@ void OpenWith(const QString &filepath, QPoint menuPosition) {
|
||||||
|
|
||||||
void Launch(const QString &filepath) {
|
void Launch(const QString &filepath) {
|
||||||
crl::on_main([=] {
|
crl::on_main([=] {
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
Platform::File::UnsafeLaunch(filepath);
|
Platform::File::UnsafeLaunch(filepath);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowInFolder(const QString &filepath) {
|
void ShowInFolder(const QString &filepath) {
|
||||||
crl::on_main([=] {
|
crl::on_main([=] {
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
Platform::File::UnsafeShowInFolder(filepath);
|
Platform::File::UnsafeShowInFolder(filepath);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -231,7 +232,7 @@ void GetOpenPath(
|
||||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||||
auto files = QStringList();
|
auto files = QStringList();
|
||||||
auto remoteContent = QByteArray();
|
auto remoteContent = QByteArray();
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
const auto success = Platform::FileDialog::Get(
|
const auto success = Platform::FileDialog::Get(
|
||||||
parent,
|
parent,
|
||||||
files,
|
files,
|
||||||
|
@ -265,7 +266,7 @@ void GetOpenPaths(
|
||||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||||
auto files = QStringList();
|
auto files = QStringList();
|
||||||
auto remoteContent = QByteArray();
|
auto remoteContent = QByteArray();
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
const auto success = Platform::FileDialog::Get(
|
const auto success = Platform::FileDialog::Get(
|
||||||
parent,
|
parent,
|
||||||
files,
|
files,
|
||||||
|
@ -314,7 +315,7 @@ void GetFolder(
|
||||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||||
auto files = QStringList();
|
auto files = QStringList();
|
||||||
auto remoteContent = QByteArray();
|
auto remoteContent = QByteArray();
|
||||||
Core::App().preventWindowActivation();
|
Ui::PreventDelayedActivation();
|
||||||
const auto success = Platform::FileDialog::Get(
|
const auto success = Platform::FileDialog::Get(
|
||||||
parent,
|
parent,
|
||||||
files,
|
files,
|
||||||
|
|
|
@ -323,7 +323,7 @@ QStringList Launcher::readArguments(int argc, char *argv[]) const {
|
||||||
auto result = QStringList();
|
auto result = QStringList();
|
||||||
result.reserve(argc);
|
result.reserve(argc);
|
||||||
for (auto i = 0; i != argc; ++i) {
|
for (auto i = 0; i != argc; ++i) {
|
||||||
result.push_back(fromUtf8Safe(argv[i]));
|
result.push_back(base::FromUtf8Safe(argv[i]));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "core/local_url_handlers.h"
|
#include "core/local_url_handlers.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "base/qthelp_regex.h"
|
#include "base/qthelp_regex.h"
|
||||||
#include "base/qthelp_url.h"
|
#include "base/qthelp_url.h"
|
||||||
#include "lang/lang_cloud_manager.h"
|
#include "lang/lang_cloud_manager.h"
|
||||||
|
@ -337,8 +338,7 @@ bool HandleUnknown(
|
||||||
const auto callback = [=](const MTPDhelp_deepLinkInfo &result) {
|
const auto callback = [=](const MTPDhelp_deepLinkInfo &result) {
|
||||||
const auto text = TextWithEntities{
|
const auto text = TextWithEntities{
|
||||||
qs(result.vmessage()),
|
qs(result.vmessage()),
|
||||||
TextUtilities::EntitiesFromMTP(
|
Api::EntitiesFromMTP(result.ventities().value_or_empty())
|
||||||
result.ventities().value_or_empty())
|
|
||||||
};
|
};
|
||||||
if (result.is_update_app()) {
|
if (result.is_update_app()) {
|
||||||
const auto box = std::make_shared<QPointer<BoxContent>>();
|
const auto box = std::make_shared<QPointer<BoxContent>>();
|
||||||
|
|
|
@ -542,30 +542,6 @@ bool Sandbox::nativeEventFilter(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sandbox::activateWindowDelayed(not_null<QWidget*> widget) {
|
|
||||||
if (_delayedActivationsPaused) {
|
|
||||||
return;
|
|
||||||
} else if (std::exchange(_windowForDelayedActivation, widget.get())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
crl::on_main(this, [=] {
|
|
||||||
if (const auto widget = base::take(_windowForDelayedActivation)) {
|
|
||||||
if (!widget->isHidden()) {
|
|
||||||
widget->activateWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sandbox::pauseDelayedWindowActivations() {
|
|
||||||
_windowForDelayedActivation = nullptr;
|
|
||||||
_delayedActivationsPaused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sandbox::resumeDelayedWindowActivations() {
|
|
||||||
_delayedActivationsPaused = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> Sandbox::widgetUpdateRequests() const {
|
rpl::producer<> Sandbox::widgetUpdateRequests() const {
|
||||||
return _widgetUpdateRequests.events();
|
return _widgetUpdateRequests.events();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,10 +48,6 @@ public:
|
||||||
return callable();
|
return callable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void activateWindowDelayed(not_null<QWidget*> widget);
|
|
||||||
void pauseDelayedWindowActivations();
|
|
||||||
void resumeDelayedWindowActivations();
|
|
||||||
|
|
||||||
rpl::producer<> widgetUpdateRequests() const;
|
rpl::producer<> widgetUpdateRequests() const;
|
||||||
|
|
||||||
ProxyData sandboxProxy() const;
|
ProxyData sandboxProxy() const;
|
||||||
|
@ -110,9 +106,6 @@ private:
|
||||||
std::vector<int> _previousLoopNestingLevels;
|
std::vector<int> _previousLoopNestingLevels;
|
||||||
std::vector<PostponedCall> _postponedCalls;
|
std::vector<PostponedCall> _postponedCalls;
|
||||||
|
|
||||||
QPointer<QWidget> _windowForDelayedActivation;
|
|
||||||
bool _delayedActivationsPaused = false;
|
|
||||||
|
|
||||||
not_null<Launcher*> _launcher;
|
not_null<Launcher*> _launcher;
|
||||||
std::unique_ptr<Application> _application;
|
std::unique_ptr<Application> _application;
|
||||||
|
|
||||||
|
|
|
@ -438,50 +438,6 @@ int GetNextRequestId() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// crc32 hash, taken somewhere from the internet
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
uint32 _crc32Table[256];
|
|
||||||
class _Crc32Initializer {
|
|
||||||
public:
|
|
||||||
_Crc32Initializer() {
|
|
||||||
uint32 poly = 0x04c11db7;
|
|
||||||
for (uint32 i = 0; i < 256; ++i) {
|
|
||||||
_crc32Table[i] = reflect(i, 8) << 24;
|
|
||||||
for (uint32 j = 0; j < 8; ++j) {
|
|
||||||
_crc32Table[i] = (_crc32Table[i] << 1) ^ (_crc32Table[i] & (1 << 31) ? poly : 0);
|
|
||||||
}
|
|
||||||
_crc32Table[i] = reflect(_crc32Table[i], 32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32 reflect(uint32 val, char ch) {
|
|
||||||
uint32 result = 0;
|
|
||||||
for (int i = 1; i < (ch + 1); ++i) {
|
|
||||||
if (val & 1) {
|
|
||||||
result |= 1 << (ch - i);
|
|
||||||
}
|
|
||||||
val >>= 1;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 hashCrc32(const void *data, uint32 len) {
|
|
||||||
static _Crc32Initializer _crc32Initializer;
|
|
||||||
|
|
||||||
const uchar *buf = (const uchar *)data;
|
|
||||||
|
|
||||||
uint32 crc(0xffffffff);
|
|
||||||
for (uint32 i = 0; i < len; ++i) {
|
|
||||||
crc = (crc >> 8) ^ _crc32Table[(crc & 0xFF) ^ buf[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return crc ^ 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 *hashSha1(const void *data, uint32 len, void *dest) {
|
int32 *hashSha1(const void *data, uint32 len, void *dest) {
|
||||||
return (int32*)SHA1((const uchar*)data, (size_t)len, (uchar*)dest);
|
return (int32*)SHA1((const uchar*)data, (size_t)len, (uchar*)dest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,8 +127,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int32 hashCrc32(const void *data, uint32 len);
|
|
||||||
|
|
||||||
int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest
|
int32 *hashSha1(const void *data, uint32 len, void *dest); // dest - ptr to 20 bytes, returns (int32*)dest
|
||||||
inline std::array<char, 20> hashSha1(const void *data, int size) {
|
inline std::array<char, 20> hashSha1(const void *data, int size) {
|
||||||
auto result = std::array<char, 20>();
|
auto result = std::array<char, 20>();
|
||||||
|
@ -198,19 +196,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline QString fromUtf8Safe(const char *str, int32 size = -1) {
|
|
||||||
if (!str || !size) return QString();
|
|
||||||
if (size < 0) size = int32(strlen(str));
|
|
||||||
QString result(QString::fromUtf8(str, size));
|
|
||||||
QByteArray back = result.toUtf8();
|
|
||||||
if (back.size() != size || memcmp(back.constData(), str, size)) return QString::fromLocal8Bit(str, size);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QString fromUtf8Safe(const QByteArray &str) {
|
|
||||||
return fromUtf8Safe(str.constData(), str.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
static const QRegularExpression::PatternOptions reMultiline(QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption);
|
static const QRegularExpression::PatternOptions reMultiline(QRegularExpression::DotMatchesEverythingOption | QRegularExpression::MultilineOption);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "ui/widgets/input_fields.h"
|
#include "ui/widgets/input_fields.h"
|
||||||
#include "chat_helpers/message_field.h"
|
#include "chat_helpers/message_field.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
@ -48,9 +49,8 @@ void applyPeerCloudDraft(PeerId peerId, const MTPDdraftMessage &draft) {
|
||||||
const auto history = Auth().data().history(peerId);
|
const auto history = Auth().data().history(peerId);
|
||||||
const auto textWithTags = TextWithTags {
|
const auto textWithTags = TextWithTags {
|
||||||
qs(draft.vmessage()),
|
qs(draft.vmessage()),
|
||||||
ConvertEntitiesToTextTags(
|
TextUtilities::ConvertEntitiesToTextTags(
|
||||||
TextUtilities::EntitiesFromMTP(
|
Api::EntitiesFromMTP(draft.ventities().value_or_empty()))
|
||||||
draft.ventities().value_or_empty()))
|
|
||||||
};
|
};
|
||||||
auto replyTo = draft.vreply_to_msg_id().value_or_empty();
|
auto replyTo = draft.vreply_to_msg_id().value_or_empty();
|
||||||
if (history->skipCloudDraft(textWithTags.text, replyTo, draft.vdate().v)) {
|
if (history->skipCloudDraft(textWithTags.text, replyTo, draft.vdate().v)) {
|
||||||
|
|
|
@ -13,7 +13,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include "base/crc32hash.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -69,7 +71,7 @@ style::color PeerUserpicColor(PeerId peerId) {
|
||||||
PeerId FakePeerIdForJustName(const QString &name) {
|
PeerId FakePeerIdForJustName(const QString &name) {
|
||||||
return peerFromUser(name.isEmpty()
|
return peerFromUser(name.isEmpty()
|
||||||
? 777
|
? 777
|
||||||
: hashCrc32(name.constData(), name.size() * sizeof(QChar)));
|
: base::crc32(name.constData(), name.size() * sizeof(QChar)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "api/api_hash.h"
|
#include "api/api_hash.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
|
@ -298,8 +299,7 @@ HistoryItem *ScheduledMessages::append(
|
||||||
message.match([&](const MTPDmessage &data) {
|
message.match([&](const MTPDmessage &data) {
|
||||||
existing->updateSentContent({
|
existing->updateSentContent({
|
||||||
qs(data.vmessage()),
|
qs(data.vmessage()),
|
||||||
TextUtilities::EntitiesFromMTP(
|
Api::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||||
data.ventities().value_or_empty())
|
|
||||||
}, data.vmedia());
|
}, data.vmedia());
|
||||||
existing->updateReplyMarkup(data.vreply_markup());
|
existing->updateReplyMarkup(data.vreply_markup());
|
||||||
existing->updateForwardedInfo(data.vfwd_from());
|
existing->updateForwardedInfo(data.vfwd_from());
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/crash_reports.h" // CrashReports::SetAnnotation
|
#include "core/crash_reports.h" // CrashReports::SetAnnotation
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
@ -1650,7 +1651,7 @@ bool Session::checkEntitiesAndViewsUpdate(const MTPDmessage &data) {
|
||||||
if (const auto existing = message(peerToChannel(peer), data.vid().v)) {
|
if (const auto existing = message(peerToChannel(peer), data.vid().v)) {
|
||||||
existing->updateSentContent({
|
existing->updateSentContent({
|
||||||
qs(data.vmessage()),
|
qs(data.vmessage()),
|
||||||
TextUtilities::EntitiesFromMTP(data.ventities().value_or_empty())
|
Api::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||||
}, data.vmedia());
|
}, data.vmedia());
|
||||||
existing->updateReplyMarkup(data.vreply_markup());
|
existing->updateReplyMarkup(data.vreply_markup());
|
||||||
existing->updateForwardedInfo(data.vfwd_from());
|
existing->updateForwardedInfo(data.vfwd_from());
|
||||||
|
@ -3676,7 +3677,7 @@ void Session::insertCheckedServiceNotification(
|
||||||
MTP_string(sending.text),
|
MTP_string(sending.text),
|
||||||
media,
|
media,
|
||||||
MTPReplyMarkup(),
|
MTPReplyMarkup(),
|
||||||
TextUtilities::EntitiesToMTP(sending.entities),
|
Api::EntitiesToMTP(sending.entities),
|
||||||
MTPint(),
|
MTPint(),
|
||||||
MTPint(),
|
MTPint(),
|
||||||
MTPstring(),
|
MTPstring(),
|
||||||
|
|
|
@ -727,7 +727,7 @@ void Widget::onDraggingScrollDelta(int delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::onDraggingScrollTimer() {
|
void Widget::onDraggingScrollTimer() {
|
||||||
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(MaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(MaxScrollSpeed));
|
auto delta = (_draggingScrollDelta > 0) ? qMin(_draggingScrollDelta * 3 / 20 + 1, int32(Ui::kMaxScrollSpeed)) : qMax(_draggingScrollDelta * 3 / 20 - 1, -int32(Ui::kMaxScrollSpeed));
|
||||||
_scroll->scrollToY(_scroll->scrollTop() + delta);
|
_scroll->scrollToY(_scroll->scrollTop() + delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,16 +169,6 @@ void showSettings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void activateClickHandler(ClickHandlerPtr handler, ClickContext context) {
|
|
||||||
crl::on_main(App::wnd(), [=] {
|
|
||||||
handler->onClick(context);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button) {
|
|
||||||
activateClickHandler(handler, ClickContext{ button });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace App
|
} // namespace App
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
|
@ -74,9 +74,6 @@ void activateBotCommand(
|
||||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||||
void showSettings();
|
void showSettings();
|
||||||
|
|
||||||
void activateClickHandler(ClickHandlerPtr handler, ClickContext context);
|
|
||||||
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
|
|
||||||
|
|
||||||
} // namespace App
|
} // namespace App
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/inactive_press.h"
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/peers/edit_participant_box.h"
|
#include "boxes/peers/edit_participant_box.h"
|
||||||
|
@ -40,6 +41,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
|
@ -515,6 +517,10 @@ QPoint InnerWidget::tooltipPos() const {
|
||||||
return _mousePosition;
|
return _mousePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InnerWidget::tooltipWindowActive() const {
|
||||||
|
return Ui::InFocusChain(window());
|
||||||
|
}
|
||||||
|
|
||||||
HistoryView::Context InnerWidget::elementContext() {
|
HistoryView::Context InnerWidget::elementContext() {
|
||||||
return HistoryView::Context::AdminLog;
|
return HistoryView::Context::AdminLog;
|
||||||
}
|
}
|
||||||
|
@ -941,7 +947,7 @@ void InnerWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
copySelectedText();
|
copySelectedText();
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
|
} else if (e->key() == Qt::Key_E && e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
TextUtilities::SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
} else {
|
} else {
|
||||||
e->ignore();
|
e->ignore();
|
||||||
|
@ -1143,7 +1149,7 @@ void InnerWidget::copyContextImage(PhotoData *photo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::copySelectedText() {
|
void InnerWidget::copySelectedText() {
|
||||||
SetClipboardText(getSelectedText());
|
TextUtilities::SetClipboardText(getSelectedText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::showStickerPackInfo(not_null<DocumentData*> document) {
|
void InnerWidget::showStickerPackInfo(not_null<DocumentData*> document) {
|
||||||
|
@ -1174,7 +1180,7 @@ void InnerWidget::openContextGif(FullMsgId itemId) {
|
||||||
|
|
||||||
void InnerWidget::copyContextText(FullMsgId itemId) {
|
void InnerWidget::copyContextText(FullMsgId itemId) {
|
||||||
if (const auto item = session().data().message(itemId)) {
|
if (const auto item = session().data().message(itemId)) {
|
||||||
SetClipboardText(HistoryItemText(item));
|
TextUtilities::SetClipboardText(HistoryItemText(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1324,8 +1330,10 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
|
||||||
_dragStartPosition = mapPointToItem(
|
_dragStartPosition = mapPointToItem(
|
||||||
mapFromGlobal(screenPos),
|
mapFromGlobal(screenPos),
|
||||||
_mouseActionItem);
|
_mouseActionItem);
|
||||||
_pressWasInactive = _controller->widget()->wasInactivePress();
|
_pressWasInactive = Ui::WasInactivePress(_controller->widget());
|
||||||
if (_pressWasInactive) _controller->widget()->setInactivePress(false);
|
if (_pressWasInactive) {
|
||||||
|
Ui::MarkInactivePress(_controller->widget(), false);
|
||||||
|
}
|
||||||
|
|
||||||
if (ClickHandler::getPressed()) {
|
if (ClickHandler::getPressed()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
@ -1412,7 +1420,7 @@ void InnerWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton but
|
||||||
|
|
||||||
if (activated) {
|
if (activated) {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
App::activateClickHandler(activated, button);
|
ActivateClickHandler(window(), activated, button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && button != Qt::RightButton) {
|
if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && button != Qt::RightButton) {
|
||||||
|
@ -1432,7 +1440,7 @@ void InnerWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton but
|
||||||
|
|
||||||
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
||||||
if (_selectedItem && _selectedText.from != _selectedText.to) {
|
if (_selectedItem && _selectedText.from != _selectedText.to) {
|
||||||
SetClipboardText(
|
TextUtilities::SetClipboardText(
|
||||||
_selectedItem->selectedText(_selectedText),
|
_selectedItem->selectedText(_selectedText),
|
||||||
QClipboard::Selection);
|
QClipboard::Selection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,7 @@ public:
|
||||||
// Ui::AbstractTooltipShower interface.
|
// Ui::AbstractTooltipShower interface.
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
// HistoryView::ElementDelegate interface.
|
// HistoryView::ElementDelegate interface.
|
||||||
HistoryView::Context elementContext() override;
|
HistoryView::Context elementContext() override;
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_service.h"
|
#include "history/history_service.h"
|
||||||
#include "history/history_message.h"
|
#include "history/history_message.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -116,7 +117,7 @@ TextWithEntities ExtractEditedText(const MTPMessage &message) {
|
||||||
const auto &data = message.c_message();
|
const auto &data = message.c_message();
|
||||||
return {
|
return {
|
||||||
TextUtilities::Clean(qs(data.vmessage())),
|
TextUtilities::Clean(qs(data.vmessage())),
|
||||||
TextUtilities::EntitiesFromMTP(data.ventities().value_or_empty())
|
Api::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -371,7 +371,7 @@ botKbScroll: defaultSolidScroll;
|
||||||
historyDateFadeDuration: 200;
|
historyDateFadeDuration: 200;
|
||||||
|
|
||||||
historyPhotoLeft: 14px;
|
historyPhotoLeft: 14px;
|
||||||
historyMessageRadius: 6px;
|
historyMessageRadius: roundRadiusLarge;
|
||||||
historyBubbleTailInLeft: icon {{ "bubble_tail", msgInBg }};
|
historyBubbleTailInLeft: icon {{ "bubble_tail", msgInBg }};
|
||||||
historyBubbleTailInLeftSelected: icon {{ "bubble_tail", msgInBgSelected }};
|
historyBubbleTailInLeftSelected: icon {{ "bubble_tail", msgInBgSelected }};
|
||||||
historyBubbleTailOutLeft: icon {{ "bubble_tail", msgOutBg }};
|
historyBubbleTailOutLeft: icon {{ "bubble_tail", msgOutBg }};
|
||||||
|
|
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/inactive_press.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
@ -50,6 +51,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_poll.h"
|
#include "data/data_poll.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
|
||||||
|
@ -826,23 +828,23 @@ void HistoryInner::touchUpdateSpeed() {
|
||||||
|
|
||||||
// fingers are inacurates, we ignore small changes to avoid stopping the autoscroll because
|
// fingers are inacurates, we ignore small changes to avoid stopping the autoscroll because
|
||||||
// of a small horizontal offset when scrolling vertically
|
// of a small horizontal offset when scrolling vertically
|
||||||
const int newSpeedY = (qAbs(pixelsPerSecond.y()) > FingerAccuracyThreshold) ? pixelsPerSecond.y() : 0;
|
const int newSpeedY = (qAbs(pixelsPerSecond.y()) > Ui::kFingerAccuracyThreshold) ? pixelsPerSecond.y() : 0;
|
||||||
const int newSpeedX = (qAbs(pixelsPerSecond.x()) > FingerAccuracyThreshold) ? pixelsPerSecond.x() : 0;
|
const int newSpeedX = (qAbs(pixelsPerSecond.x()) > Ui::kFingerAccuracyThreshold) ? pixelsPerSecond.x() : 0;
|
||||||
if (_touchScrollState == Ui::TouchScrollState::Auto) {
|
if (_touchScrollState == Ui::TouchScrollState::Auto) {
|
||||||
const int oldSpeedY = _touchSpeed.y();
|
const int oldSpeedY = _touchSpeed.y();
|
||||||
const int oldSpeedX = _touchSpeed.x();
|
const int oldSpeedX = _touchSpeed.x();
|
||||||
if ((oldSpeedY <= 0 && newSpeedY <= 0) || ((oldSpeedY >= 0 && newSpeedY >= 0)
|
if ((oldSpeedY <= 0 && newSpeedY <= 0) || ((oldSpeedY >= 0 && newSpeedY >= 0)
|
||||||
&& (oldSpeedX <= 0 && newSpeedX <= 0)) || (oldSpeedX >= 0 && newSpeedX >= 0)) {
|
&& (oldSpeedX <= 0 && newSpeedX <= 0)) || (oldSpeedX >= 0 && newSpeedX >= 0)) {
|
||||||
_touchSpeed.setY(snap((oldSpeedY + (newSpeedY / 4)), -MaxScrollAccelerated, +MaxScrollAccelerated));
|
_touchSpeed.setY(snap((oldSpeedY + (newSpeedY / 4)), -Ui::kMaxScrollAccelerated, +Ui::kMaxScrollAccelerated));
|
||||||
_touchSpeed.setX(snap((oldSpeedX + (newSpeedX / 4)), -MaxScrollAccelerated, +MaxScrollAccelerated));
|
_touchSpeed.setX(snap((oldSpeedX + (newSpeedX / 4)), -Ui::kMaxScrollAccelerated, +Ui::kMaxScrollAccelerated));
|
||||||
} else {
|
} else {
|
||||||
_touchSpeed = QPoint();
|
_touchSpeed = QPoint();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we average the speed to avoid strange effects with the last delta
|
// we average the speed to avoid strange effects with the last delta
|
||||||
if (!_touchSpeed.isNull()) {
|
if (!_touchSpeed.isNull()) {
|
||||||
_touchSpeed.setX(snap((_touchSpeed.x() / 4) + (newSpeedX * 3 / 4), -MaxScrollFlick, +MaxScrollFlick));
|
_touchSpeed.setX(snap((_touchSpeed.x() / 4) + (newSpeedX * 3 / 4), -Ui::kMaxScrollFlick, +Ui::kMaxScrollFlick));
|
||||||
_touchSpeed.setY(snap((_touchSpeed.y() / 4) + (newSpeedY * 3 / 4), -MaxScrollFlick, +MaxScrollFlick));
|
_touchSpeed.setY(snap((_touchSpeed.y() / 4) + (newSpeedY * 3 / 4), -Ui::kMaxScrollFlick, +Ui::kMaxScrollFlick));
|
||||||
} else {
|
} else {
|
||||||
_touchSpeed = QPoint(newSpeedX, newSpeedY);
|
_touchSpeed = QPoint(newSpeedX, newSpeedY);
|
||||||
}
|
}
|
||||||
|
@ -1033,8 +1035,10 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||||
? mouseActionView->data().get()
|
? mouseActionView->data().get()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
_dragStartPosition = mapPointToItem(mapFromGlobal(screenPos), mouseActionView);
|
_dragStartPosition = mapPointToItem(mapFromGlobal(screenPos), mouseActionView);
|
||||||
_pressWasInactive = _controller->widget()->wasInactivePress();
|
_pressWasInactive = Ui::WasInactivePress(_controller->widget());
|
||||||
if (_pressWasInactive) _controller->widget()->setInactivePress(false);
|
if (_pressWasInactive) {
|
||||||
|
Ui::MarkInactivePress(_controller->widget(), false);
|
||||||
|
}
|
||||||
|
|
||||||
if (ClickHandler::getPressed()) {
|
if (ClickHandler::getPressed()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
@ -1187,7 +1191,7 @@ std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
|
||||||
}
|
}
|
||||||
return TextForMimeData();
|
return TextForMimeData();
|
||||||
}();
|
}();
|
||||||
if (auto mimeData = MimeDataFromText(selectedText)) {
|
if (auto mimeData = TextUtilities::MimeDataFromText(selectedText)) {
|
||||||
updateDragSelection(nullptr, nullptr, false);
|
updateDragSelection(nullptr, nullptr, false);
|
||||||
_widget->noSelectingScroll();
|
_widget->noSelectingScroll();
|
||||||
|
|
||||||
|
@ -1343,7 +1347,7 @@ void HistoryInner::mouseActionFinish(
|
||||||
const auto pressedItemId = pressedItemView
|
const auto pressedItemId = pressedItemView
|
||||||
? pressedItemView->data()->fullId()
|
? pressedItemView->data()->fullId()
|
||||||
: FullMsgId();
|
: FullMsgId();
|
||||||
App::activateClickHandler(activated, {
|
ActivateClickHandler(window(), activated, {
|
||||||
button,
|
button,
|
||||||
QVariant::fromValue(pressedItemId)
|
QVariant::fromValue(pressedItemId)
|
||||||
});
|
});
|
||||||
|
@ -1401,7 +1405,7 @@ void HistoryInner::mouseActionFinish(
|
||||||
if (!_selected.empty() && _selected.cbegin()->second != FullSelection) {
|
if (!_selected.empty() && _selected.cbegin()->second != FullSelection) {
|
||||||
const auto [item, selection] = *_selected.cbegin();
|
const auto [item, selection] = *_selected.cbegin();
|
||||||
if (const auto view = item->mainView()) {
|
if (const auto view = item->mainView()) {
|
||||||
SetClipboardText(
|
TextUtilities::SetClipboardText(
|
||||||
view->selectedText(selection),
|
view->selectedText(selection),
|
||||||
QClipboard::Selection);
|
QClipboard::Selection);
|
||||||
}
|
}
|
||||||
|
@ -1818,7 +1822,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::copySelectedText() {
|
void HistoryInner::copySelectedText() {
|
||||||
SetClipboardText(getSelectedText());
|
TextUtilities::SetClipboardText(getSelectedText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
|
void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
|
||||||
|
@ -1893,9 +1897,9 @@ void HistoryInner::saveContextGif(FullMsgId itemId) {
|
||||||
void HistoryInner::copyContextText(FullMsgId itemId) {
|
void HistoryInner::copyContextText(FullMsgId itemId) {
|
||||||
if (const auto item = session().data().message(itemId)) {
|
if (const auto item = session().data().message(itemId)) {
|
||||||
if (const auto group = session().data().groups().find(item)) {
|
if (const auto group = session().data().groups().find(item)) {
|
||||||
SetClipboardText(HistoryGroupText(group));
|
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||||
} else {
|
} else {
|
||||||
SetClipboardText(HistoryItemText(item));
|
TextUtilities::SetClipboardText(HistoryItemText(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1986,7 +1990,7 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
} else if (e->key() == Qt::Key_E
|
} else if (e->key() == Qt::Key_E
|
||||||
&& e->modifiers().testFlag(Qt::ControlModifier)) {
|
&& e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
TextUtilities::SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
} else if (e == QKeySequence::Delete) {
|
} else if (e == QKeySequence::Delete) {
|
||||||
auto selectedState = getSelectionState();
|
auto selectedState = getSelectionState();
|
||||||
|
@ -3194,6 +3198,10 @@ QPoint HistoryInner::tooltipPos() const {
|
||||||
return _mousePosition;
|
return _mousePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HistoryInner::tooltipWindowActive() const {
|
||||||
|
return Ui::InFocusChain(window());
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryInner::onParentGeometryChanged() {
|
void HistoryInner::onParentGeometryChanged() {
|
||||||
auto mousePos = QCursor::pos();
|
auto mousePos = QCursor::pos();
|
||||||
auto mouseOver = _widget->rect().contains(_widget->mapFromGlobal(mousePos));
|
auto mouseOver = _widget->rect().contains(_widget->mapFromGlobal(mousePos));
|
||||||
|
|
|
@ -110,6 +110,7 @@ public:
|
||||||
// Ui::AbstractTooltipShower interface.
|
// Ui::AbstractTooltipShower interface.
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
// HistoryView::ElementDelegate interface.
|
// HistoryView::ElementDelegate interface.
|
||||||
static not_null<HistoryView::ElementDelegate*> ElementDelegate();
|
static not_null<HistoryView::ElementDelegate*> ElementDelegate();
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
#include "history/history_location_manager.h"
|
#include "history/history_location_manager.h"
|
||||||
|
@ -442,7 +443,7 @@ HistoryMessage::HistoryMessage(
|
||||||
}
|
}
|
||||||
setText({
|
setText({
|
||||||
TextUtilities::Clean(qs(data.vmessage())),
|
TextUtilities::Clean(qs(data.vmessage())),
|
||||||
TextUtilities::EntitiesFromMTP(data.ventities().value_or_empty())
|
Api::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||||
});
|
});
|
||||||
if (const auto groupedId = data.vgrouped_id()) {
|
if (const auto groupedId = data.vgrouped_id()) {
|
||||||
setGroupId(
|
setGroupId(
|
||||||
|
@ -1051,7 +1052,7 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) {
|
||||||
|
|
||||||
const auto textWithEntities = TextWithEntities{
|
const auto textWithEntities = TextWithEntities{
|
||||||
qs(message.vmessage()),
|
qs(message.vmessage()),
|
||||||
TextUtilities::EntitiesFromMTP(message.ventities().value_or_empty())
|
Api::EntitiesFromMTP(message.ventities().value_or_empty())
|
||||||
};
|
};
|
||||||
setReplyMarkup(message.vreply_markup());
|
setReplyMarkup(message.vreply_markup());
|
||||||
if (!isLocalUpdateMedia()) {
|
if (!isLocalUpdateMedia()) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_widget.h"
|
#include "history/history_widget.h"
|
||||||
|
|
||||||
#include "api/api_sending.h"
|
#include "api/api_sending.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
#include "boxes/send_files_box.h"
|
#include "boxes/send_files_box.h"
|
||||||
#include "boxes/share_box.h"
|
#include "boxes/share_box.h"
|
||||||
|
@ -77,6 +78,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/unread_badge.h"
|
#include "ui/unread_badge.h"
|
||||||
|
#include "ui/delayed_activation.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
|
@ -133,7 +135,7 @@ ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
||||||
void ActivateWindow(not_null<Window::SessionController*> controller) {
|
void ActivateWindow(not_null<Window::SessionController*> controller) {
|
||||||
const auto window = controller->widget();
|
const auto window = controller->widget();
|
||||||
window->activateWindow();
|
window->activateWindow();
|
||||||
Core::App().activateWindowDelayed(window);
|
Ui::ActivateWindowDelayed(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShowHistoryEndInsteadOfUnread(
|
bool ShowHistoryEndInsteadOfUnread(
|
||||||
|
@ -2833,7 +2835,9 @@ void HistoryWidget::saveEditMsg() {
|
||||||
_history,
|
_history,
|
||||||
session().user()).flags;
|
session().user()).flags;
|
||||||
auto sending = TextWithEntities();
|
auto sending = TextWithEntities();
|
||||||
auto left = TextWithEntities { textWithTags.text, ConvertTextTagsToEntities(textWithTags.tags) };
|
auto left = TextWithEntities {
|
||||||
|
textWithTags.text,
|
||||||
|
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
|
||||||
TextUtilities::PrepareForSending(left, prepareFlags);
|
TextUtilities::PrepareForSending(left, prepareFlags);
|
||||||
|
|
||||||
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
||||||
|
@ -2854,8 +2858,10 @@ void HistoryWidget::saveEditMsg() {
|
||||||
if (webPageId == CancelledWebPageId) {
|
if (webPageId == CancelledWebPageId) {
|
||||||
sendFlags |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
sendFlags |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
||||||
}
|
}
|
||||||
auto localEntities = TextUtilities::EntitiesToMTP(sending.entities);
|
auto localEntities = Api::EntitiesToMTP(sending.entities);
|
||||||
auto sentEntities = TextUtilities::EntitiesToMTP(sending.entities, TextUtilities::ConvertOption::SkipLocal);
|
auto sentEntities = Api::EntitiesToMTP(
|
||||||
|
sending.entities,
|
||||||
|
Api::ConvertOption::SkipLocal);
|
||||||
if (!sentEntities.v.isEmpty()) {
|
if (!sentEntities.v.isEmpty()) {
|
||||||
sendFlags |= MTPmessages_EditMessage::Flag::f_entities;
|
sendFlags |= MTPmessages_EditMessage::Flag::f_entities;
|
||||||
}
|
}
|
||||||
|
@ -4497,14 +4503,14 @@ void HistoryWidget::sendFileConfirmed(
|
||||||
|
|
||||||
auto caption = TextWithEntities{
|
auto caption = TextWithEntities{
|
||||||
file->caption.text,
|
file->caption.text,
|
||||||
ConvertTextTagsToEntities(file->caption.tags)
|
TextUtilities::ConvertTextTagsToEntities(file->caption.tags)
|
||||||
};
|
};
|
||||||
const auto prepareFlags = Ui::ItemTextOptions(
|
const auto prepareFlags = Ui::ItemTextOptions(
|
||||||
history,
|
history,
|
||||||
session().user()).flags;
|
session().user()).flags;
|
||||||
TextUtilities::PrepareForSending(caption, prepareFlags);
|
TextUtilities::PrepareForSending(caption, prepareFlags);
|
||||||
TextUtilities::Trim(caption);
|
TextUtilities::Trim(caption);
|
||||||
auto localEntities = TextUtilities::EntitiesToMTP(caption.entities);
|
auto localEntities = Api::EntitiesToMTP(caption.entities);
|
||||||
|
|
||||||
if (itemToEdit) {
|
if (itemToEdit) {
|
||||||
if (const auto id = itemToEdit->groupId()) {
|
if (const auto id = itemToEdit->groupId()) {
|
||||||
|
@ -6870,7 +6876,7 @@ QPoint HistoryWidget::clampMousePosition(QPoint point) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onScrollTimer() {
|
void HistoryWidget::onScrollTimer() {
|
||||||
auto d = (_scrollDelta > 0) ? qMin(_scrollDelta * 3 / 20 + 1, int32(MaxScrollSpeed)) : qMax(_scrollDelta * 3 / 20 - 1, -int32(MaxScrollSpeed));
|
auto d = (_scrollDelta > 0) ? qMin(_scrollDelta * 3 / 20 + 1, int32(Ui::kMaxScrollSpeed)) : qMax(_scrollDelta * 3 / 20 - 1, -int32(Ui::kMaxScrollSpeed));
|
||||||
_scroll->scrollToY(_scroll->scrollTop() + d);
|
_scroll->scrollToY(_scroll->scrollTop() + d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_groups.h"
|
#include "data/data_groups.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "core/file_utilities.h"
|
#include "core/file_utilities.h"
|
||||||
#include "platform/platform_info.h"
|
#include "platform/platform_info.h"
|
||||||
#include "window/window_peer_menu.h"
|
#include "window/window_peer_menu.h"
|
||||||
|
@ -576,7 +577,7 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
|
||||||
? tr::lng_context_copy_selected(tr::now)
|
? tr::lng_context_copy_selected(tr::now)
|
||||||
: tr::lng_context_copy_selected_items(tr::now);
|
: tr::lng_context_copy_selected_items(tr::now);
|
||||||
result->addAction(text, [=] {
|
result->addAction(text, [=] {
|
||||||
SetClipboardText(list->getSelectedText());
|
TextUtilities::SetClipboardText(list->getSelectedText());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,11 +610,11 @@ base::unique_qptr<Ui::PopupMenu> FillContextMenu(
|
||||||
if (const auto item = owner->message(itemId)) {
|
if (const auto item = owner->message(itemId)) {
|
||||||
if (asGroup) {
|
if (asGroup) {
|
||||||
if (const auto group = owner->groups().find(item)) {
|
if (const auto group = owner->groups().find(item)) {
|
||||||
SetClipboardText(HistoryGroupText(group));
|
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SetClipboardText(HistoryItemText(item));
|
TextUtilities::SetClipboardText(HistoryItemText(item));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
|
#include "ui/inactive_press.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "boxes/peers/edit_participant_box.h"
|
#include "boxes/peers/edit_participant_box.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -1090,6 +1091,10 @@ QPoint ListWidget::tooltipPos() const {
|
||||||
return _mousePosition;
|
return _mousePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ListWidget::tooltipWindowActive() const {
|
||||||
|
return Ui::InFocusChain(window());
|
||||||
|
}
|
||||||
|
|
||||||
Context ListWidget::elementContext() {
|
Context ListWidget::elementContext() {
|
||||||
return _delegate->listContext();
|
return _delegate->listContext();
|
||||||
}
|
}
|
||||||
|
@ -1545,11 +1550,11 @@ void ListWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
}
|
}
|
||||||
} else if (e == QKeySequence::Copy
|
} else if (e == QKeySequence::Copy
|
||||||
&& (hasSelectedText() || hasSelectedItems())) {
|
&& (hasSelectedText() || hasSelectedItems())) {
|
||||||
SetClipboardText(getSelectedText());
|
TextUtilities::SetClipboardText(getSelectedText());
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
} else if (e->key() == Qt::Key_E
|
} else if (e->key() == Qt::Key_E
|
||||||
&& e->modifiers().testFlag(Qt::ControlModifier)) {
|
&& e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||||
SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
TextUtilities::SetClipboardText(getSelectedText(), QClipboard::FindBuffer);
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
} else if (e == QKeySequence::Delete) {
|
} else if (e == QKeySequence::Delete) {
|
||||||
_delegate->listDeleteRequest();
|
_delegate->listDeleteRequest();
|
||||||
|
@ -1893,8 +1898,10 @@ void ListWidget::mouseActionStart(
|
||||||
const auto pressElement = _overElement;
|
const auto pressElement = _overElement;
|
||||||
|
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
_pressWasInactive = _controller->widget()->wasInactivePress();
|
_pressWasInactive = Ui::WasInactivePress(_controller->widget());
|
||||||
if (_pressWasInactive) _controller->widget()->setInactivePress(false);
|
if (_pressWasInactive) {
|
||||||
|
Ui::MarkInactivePress(_controller->widget(), false);
|
||||||
|
}
|
||||||
|
|
||||||
if (ClickHandler::getPressed()) {
|
if (ClickHandler::getPressed()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
@ -2016,7 +2023,7 @@ void ListWidget::mouseActionFinish(
|
||||||
activated = nullptr;
|
activated = nullptr;
|
||||||
} else if (activated) {
|
} else if (activated) {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
App::activateClickHandler(activated, {
|
ActivateClickHandler(window(), activated, {
|
||||||
button,
|
button,
|
||||||
QVariant::fromValue(pressState.itemId)
|
QVariant::fromValue(pressState.itemId)
|
||||||
});
|
});
|
||||||
|
@ -2058,7 +2065,7 @@ void ListWidget::mouseActionFinish(
|
||||||
if (_selectedTextItem
|
if (_selectedTextItem
|
||||||
&& _selectedTextRange.from != _selectedTextRange.to) {
|
&& _selectedTextRange.from != _selectedTextRange.to) {
|
||||||
if (const auto view = viewForItem(_selectedTextItem)) {
|
if (const auto view = viewForItem(_selectedTextItem)) {
|
||||||
SetClipboardText(
|
TextUtilities::SetClipboardText(
|
||||||
view->selectedText(_selectedTextRange),
|
view->selectedText(_selectedTextRange),
|
||||||
QClipboard::Selection);
|
QClipboard::Selection);
|
||||||
}
|
}
|
||||||
|
@ -2303,7 +2310,7 @@ std::unique_ptr<QMimeData> ListWidget::prepareDrag() {
|
||||||
}
|
}
|
||||||
return TextForMimeData();
|
return TextForMimeData();
|
||||||
}();
|
}();
|
||||||
if (auto mimeData = MimeDataFromText(selectedText)) {
|
if (auto mimeData = TextUtilities::MimeDataFromText(selectedText)) {
|
||||||
clearDragSelection();
|
clearDragSelection();
|
||||||
// _widget->noSelectingScroll(); #TODO scroll
|
// _widget->noSelectingScroll(); #TODO scroll
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@ public:
|
||||||
// AbstractTooltipShower interface
|
// AbstractTooltipShower interface
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
// ElementDelegate interface.
|
// ElementDelegate interface.
|
||||||
Context elementContext() override;
|
Context elementContext() override;
|
||||||
|
|
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "styles/style_history.h"
|
#include "styles/style_history.h"
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "window/window_session_controller.h" // isGifPausedAtLeastFor.
|
#include "window/window_session_controller.h" // isGifPausedAtLeastFor.
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "lottie/lottie_single_player.h"
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "styles/style_history.h"
|
#include "styles/style_history.h"
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "storage/file_download.h"
|
#include "storage/file_download.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/inactive_press.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
@ -1823,8 +1824,13 @@ void ListWidget::mouseActionStart(
|
||||||
auto pressLayout = _overLayout;
|
auto pressLayout = _overLayout;
|
||||||
|
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
_pressWasInactive = _controller->parentController()->widget()->wasInactivePress();
|
_pressWasInactive = Ui::WasInactivePress(
|
||||||
if (_pressWasInactive) _controller->parentController()->widget()->setInactivePress(false);
|
_controller->parentController()->widget());
|
||||||
|
if (_pressWasInactive) {
|
||||||
|
Ui::MarkInactivePress(
|
||||||
|
_controller->parentController()->widget(),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
if (ClickHandler::getPressed() && !hasSelected()) {
|
if (ClickHandler::getPressed() && !hasSelected()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
@ -2018,7 +2024,7 @@ void ListWidget::mouseActionFinish(
|
||||||
_wasSelectedText = false;
|
_wasSelectedText = false;
|
||||||
if (activated) {
|
if (activated) {
|
||||||
mouseActionCancel();
|
mouseActionCancel();
|
||||||
App::activateClickHandler(activated, button);
|
ActivateClickHandler(window(), activated, button);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2045,7 +2051,7 @@ void ListWidget::mouseActionFinish(
|
||||||
|
|
||||||
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
||||||
//if (hasSelectedText()) { // #TODO linux clipboard
|
//if (hasSelectedText()) { // #TODO linux clipboard
|
||||||
// SetClipboardText(_selected.cbegin()->first->selectedText(_selected.cbegin()->second), QClipboard::Selection);
|
// TextUtilities::SetClipboardText(_selected.cbegin()->first->selectedText(_selected.cbegin()->second), QClipboard::Selection);
|
||||||
//}
|
//}
|
||||||
#endif // Q_OS_LINUX32 || Q_OS_LINUX64
|
#endif // Q_OS_LINUX32 || Q_OS_LINUX64
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -136,7 +137,7 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
|
||||||
case mtpc_botInlineMessageMediaAuto: {
|
case mtpc_botInlineMessageMediaAuto: {
|
||||||
const auto &r = message->c_botInlineMessageMediaAuto();
|
const auto &r = message->c_botInlineMessageMediaAuto();
|
||||||
const auto message = qs(r.vmessage());
|
const auto message = qs(r.vmessage());
|
||||||
const auto entities = TextUtilities::EntitiesFromMTP(
|
const auto entities = Api::EntitiesFromMTP(
|
||||||
r.ventities().value_or_empty());
|
r.ventities().value_or_empty());
|
||||||
if (result->_type == Type::Photo) {
|
if (result->_type == Type::Photo) {
|
||||||
if (!result->_photo) {
|
if (!result->_photo) {
|
||||||
|
@ -168,7 +169,7 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
|
||||||
const auto &r = message->c_botInlineMessageText();
|
const auto &r = message->c_botInlineMessageText();
|
||||||
result->sendData = std::make_unique<internal::SendText>(
|
result->sendData = std::make_unique<internal::SendText>(
|
||||||
qs(r.vmessage()),
|
qs(r.vmessage()),
|
||||||
TextUtilities::EntitiesFromMTP(r.ventities().value_or_empty()),
|
Api::EntitiesFromMTP(r.ventities().value_or_empty()),
|
||||||
r.is_no_webpage());
|
r.is_no_webpage());
|
||||||
if (result->_type == Type::Photo) {
|
if (result->_type == Type::Photo) {
|
||||||
if (!result->_photo) {
|
if (!result->_photo) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "inline_bots/inline_bot_send_data.h"
|
#include "inline_bots/inline_bot_send_data.h"
|
||||||
|
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
@ -78,7 +79,7 @@ QString SendDataCommon::getErrorOnSend(
|
||||||
SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const {
|
SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const {
|
||||||
SentMTPMessageFields result;
|
SentMTPMessageFields result;
|
||||||
result.text = MTP_string(_message);
|
result.text = MTP_string(_message);
|
||||||
result.entities = TextUtilities::EntitiesToMTP(_entities);
|
result.entities = Api::EntitiesToMTP(_entities);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,10 @@ QPoint Inner::tooltipPos() const {
|
||||||
return _lastMousePos;
|
return _lastMousePos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Inner::tooltipWindowActive() const {
|
||||||
|
return Ui::InFocusChain(window());
|
||||||
|
}
|
||||||
|
|
||||||
Inner::~Inner() = default;
|
Inner::~Inner() = default;
|
||||||
|
|
||||||
void Inner::paintEvent(QPaintEvent *e) {
|
void Inner::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -239,7 +243,7 @@ void Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
int row = _selected / MatrixRowShift, column = _selected % MatrixRowShift;
|
int row = _selected / MatrixRowShift, column = _selected % MatrixRowShift;
|
||||||
selectInlineResult(row, column);
|
selectInlineResult(row, column);
|
||||||
} else {
|
} else {
|
||||||
App::activateClickHandler(activated, e->button());
|
ActivateClickHandler(window(), activated, e->button());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -926,8 +930,7 @@ void Widget::startShowAnimation() {
|
||||||
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, Ui::PanelAnimation::Origin::BottomLeft);
|
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, Ui::PanelAnimation::Origin::BottomLeft);
|
||||||
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
||||||
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
||||||
auto corners = App::cornersMask(ImageRoundRadius::Small);
|
_showAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||||
_showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]);
|
|
||||||
_showAnimation->start();
|
_showAnimation->start();
|
||||||
}
|
}
|
||||||
hideChildren();
|
hideChildren();
|
||||||
|
|
|
@ -86,6 +86,7 @@ public:
|
||||||
// Ui::AbstractTooltipShower interface.
|
// Ui::AbstractTooltipShower interface.
|
||||||
QString tooltipText() const override;
|
QString tooltipText() const override;
|
||||||
QPoint tooltipPos() const override;
|
QPoint tooltipPos() const override;
|
||||||
|
bool tooltipWindowActive() const override;
|
||||||
|
|
||||||
~Inner();
|
~Inner();
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
|
#include "ui/special_fields.h"
|
||||||
#include "main/main_account.h"
|
#include "main/main_account.h"
|
||||||
#include "boxes/confirm_phone_box.h"
|
#include "boxes/confirm_phone_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_scheduled_messages.h"
|
#include "data/data_scheduled_messages.h"
|
||||||
|
#include "api/api_text_entities.h"
|
||||||
#include "ui/special_buttons.h"
|
#include "ui/special_buttons.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
|
@ -3818,7 +3819,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
|
||||||
}
|
}
|
||||||
item->updateSentContent({
|
item->updateSentContent({
|
||||||
sent.text,
|
sent.text,
|
||||||
TextUtilities::EntitiesFromMTP(list.value_or_empty())
|
Api::EntitiesFromMTP(list.value_or_empty())
|
||||||
}, d.vmedia());
|
}, d.vmedia());
|
||||||
item->contributeToSlowmode(d.vdate().v);
|
item->contributeToSlowmode(d.vdate().v);
|
||||||
if (!wasAlready) {
|
if (!wasAlready) {
|
||||||
|
@ -4321,7 +4322,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
const auto &d = update.c_updateServiceNotification();
|
const auto &d = update.c_updateServiceNotification();
|
||||||
const auto text = TextWithEntities {
|
const auto text = TextWithEntities {
|
||||||
qs(d.vmessage()),
|
qs(d.vmessage()),
|
||||||
TextUtilities::EntitiesFromMTP(d.ventities().v)
|
Api::EntitiesFromMTP(d.ventities().v)
|
||||||
};
|
};
|
||||||
if (IsForceLogoutNotification(d)) {
|
if (IsForceLogoutNotification(d)) {
|
||||||
Core::App().forceLogOut(text);
|
Core::App().forceLogOut(text);
|
||||||
|
|
|
@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "lang/lang_cloud_manager.h"
|
#include "lang/lang_cloud_manager.h"
|
||||||
|
@ -154,6 +155,11 @@ void MainWindow::firstShow() {
|
||||||
|
|
||||||
psFirstShow();
|
psFirstShow();
|
||||||
updateTrayMenu();
|
updateTrayMenu();
|
||||||
|
|
||||||
|
windowDeactivateEvents(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
Ui::Tooltip::Hide();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::clearWidgetsHook() {
|
void MainWindow::clearWidgetsHook() {
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
|
#include "ui/platform/ui_platform_utility.h"
|
||||||
#include "ui/toast/toast.h"
|
#include "ui/toast/toast.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
|
@ -1115,9 +1116,9 @@ void OverlayWidget::onSaveAs() {
|
||||||
filter = mimeType.filterString() + qsl(";;") + FileDialog::AllFilesFilter();
|
filter = mimeType.filterString() + qsl(";;") + FileDialog::AllFilesFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
psBringToBack(this);
|
Ui::Platform::BringToBack(this);
|
||||||
file = FileNameForSave(tr::lng_save_file(tr::now), filter, qsl("doc"), name, true, alreadyDir);
|
file = FileNameForSave(tr::lng_save_file(tr::now), filter, qsl("doc"), name, true, alreadyDir);
|
||||||
psShowOverAll(this);
|
Ui::Platform::ShowOverAll(this);
|
||||||
if (!file.isEmpty() && file != location.name()) {
|
if (!file.isEmpty() && file != location.name()) {
|
||||||
if (_doc->data().isEmpty()) {
|
if (_doc->data().isEmpty()) {
|
||||||
QFile(file).remove();
|
QFile(file).remove();
|
||||||
|
@ -1141,7 +1142,7 @@ void OverlayWidget::onSaveAs() {
|
||||||
} else {
|
} else {
|
||||||
if (!_photo || !_photo->loaded()) return;
|
if (!_photo || !_photo->loaded()) return;
|
||||||
|
|
||||||
psBringToBack(this);
|
Ui::Platform::BringToBack(this);
|
||||||
auto filter = qsl("JPEG Image (*.jpg);;") + FileDialog::AllFilesFilter();
|
auto filter = qsl("JPEG Image (*.jpg);;") + FileDialog::AllFilesFilter();
|
||||||
FileDialog::GetWritePath(
|
FileDialog::GetWritePath(
|
||||||
this,
|
this,
|
||||||
|
@ -1153,13 +1154,13 @@ void OverlayWidget::onSaveAs() {
|
||||||
QString(),
|
QString(),
|
||||||
false,
|
false,
|
||||||
_photo->date),
|
_photo->date),
|
||||||
crl::guard(this, [this, photo = _photo](const QString &result) {
|
crl::guard(this, [=, photo = _photo](const QString &result) {
|
||||||
if (!result.isEmpty() && _photo == photo && photo->loaded()) {
|
if (!result.isEmpty() && _photo == photo && photo->loaded()) {
|
||||||
photo->large()->original().save(result, "JPG");
|
photo->large()->original().save(result, "JPG");
|
||||||
}
|
}
|
||||||
psShowOverAll(this);
|
Ui::Platform::ShowOverAll(this);
|
||||||
}), crl::guard(this, [this] {
|
}), crl::guard(this, [=] {
|
||||||
psShowOverAll(this);
|
Ui::Platform::ShowOverAll(this);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
activateWindow();
|
activateWindow();
|
||||||
|
@ -1977,13 +1978,13 @@ void OverlayWidget::updateThemePreviewGeometry() {
|
||||||
void OverlayWidget::displayFinished() {
|
void OverlayWidget::displayFinished() {
|
||||||
updateControls();
|
updateControls();
|
||||||
if (isHidden()) {
|
if (isHidden()) {
|
||||||
psUpdateOverlayed(this);
|
Ui::Platform::UpdateOverlayed(this);
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
showFullScreen();
|
showFullScreen();
|
||||||
#else // Q_OS_LINUX
|
#else // Q_OS_LINUX
|
||||||
show();
|
show();
|
||||||
#endif // Q_OS_LINUX
|
#endif // Q_OS_LINUX
|
||||||
psShowOverAll(this);
|
Ui::Platform::ShowOverAll(this);
|
||||||
activateWindow();
|
activateWindow();
|
||||||
QApplication::setActiveWindow(this);
|
QApplication::setActiveWindow(this);
|
||||||
setFocus();
|
setFocus();
|
||||||
|
@ -3497,7 +3498,7 @@ void OverlayWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
showSaveMsgFile();
|
showSaveMsgFile();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
App::activateClickHandler(activated, e->button());
|
ActivateClickHandler(this, activated, e->button());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
#include "ui/wrap/fade_wrap.h"
|
#include "ui/wrap/fade_wrap.h"
|
||||||
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
||||||
|
#include "ui/special_fields.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "boxes/confirm_phone_box.h"
|
#include "boxes/confirm_phone_box.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
|
|
@ -23,7 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
#include <QtCore/QProcess>
|
#include <QtCore/QProcess>
|
||||||
#include <QtCore/QVersionNumber>
|
#include <QtCore/QVersionNumber>
|
||||||
#include <qpa/qplatformnativeinterface.h>
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
@ -92,10 +91,6 @@ void FallbackFontConfig() {
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
bool IsApplicationActive() {
|
|
||||||
return QApplication::activeWindow() != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetApplicationIcon(const QIcon &icon) {
|
void SetApplicationIcon(const QIcon &icon) {
|
||||||
QApplication::setWindowIcon(icon);
|
QApplication::setWindowIcon(icon);
|
||||||
}
|
}
|
||||||
|
@ -135,12 +130,6 @@ QRect psDesktopRect() {
|
||||||
return _monitorRect;
|
return _monitorRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psShowOverAll(QWidget *w, bool canFocus) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void psBringToBack(QWidget *w) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void psWriteDump() {
|
void psWriteDump() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,29 +232,6 @@ void finish() {
|
||||||
Notifications::Finish();
|
Notifications::Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslucentWindowsSupported(QPoint globalPosition) {
|
|
||||||
if (const auto native = QGuiApplication::platformNativeInterface()) {
|
|
||||||
if (const auto desktop = QApplication::desktop()) {
|
|
||||||
const auto index = desktop->screenNumber(globalPosition);
|
|
||||||
const auto screens = QGuiApplication::screens();
|
|
||||||
if (const auto screen = (index >= 0 && index < screens.size()) ? screens[index] : QGuiApplication::primaryScreen()) {
|
|
||||||
if (native->nativeResourceForScreen(QByteArray("compositingEnabled"), screen)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto WarnedAbout = base::flat_set<int>();
|
|
||||||
if (!WarnedAbout.contains(index)) {
|
|
||||||
WarnedAbout.insert(index);
|
|
||||||
LOG(("WARNING: Compositing is disabled for screen index %1 (for position %2,%3)").arg(index).arg(globalPosition.x()).arg(globalPosition.y()));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(("WARNING: Could not get screen for index %1 (for position %2,%3)").arg(index).arg(globalPosition.x()).arg(globalPosition.y()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterCustomScheme() {
|
void RegisterCustomScheme() {
|
||||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||||
auto home = getHomeDir();
|
auto home = getHomeDir();
|
||||||
|
@ -432,9 +398,6 @@ void psAutoStart(bool start, bool silent) {
|
||||||
void psSendToMenu(bool send, bool silent) {
|
void psSendToMenu(bool send, bool silent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void psUpdateOverlayed(QWidget *widget) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool linuxMoveFile(const char *from, const char *to) {
|
bool linuxMoveFile(const char *from, const char *to) {
|
||||||
FILE *ffrom = fopen(from, "rb"), *fto = fopen(to, "wb");
|
FILE *ffrom = fopen(from, "rb"), *fto = fopen(to, "wb");
|
||||||
if (!ffrom) {
|
if (!ffrom) {
|
||||||
|
|
|
@ -20,26 +20,15 @@ namespace Platform {
|
||||||
inline void SetWatchingMediaKeys(bool watching) {
|
inline void SetWatchingMediaKeys(bool watching) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsApplicationActive();
|
|
||||||
|
|
||||||
inline void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void InitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DeInitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ReInitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CurrentExecutablePath(int argc, char *argv[]);
|
QString CurrentExecutablePath(int argc, char *argv[]);
|
||||||
|
|
||||||
inline std::optional<crl::time> LastUserInputTime() {
|
inline std::optional<crl::time> LastUserInputTime() {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void IgnoreApplicationActivationRightNow() {
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr bool UseMainQueueGeneric() {
|
inline constexpr bool UseMainQueueGeneric() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -70,15 +59,12 @@ void psAutoStart(bool start, bool silent = false);
|
||||||
void psSendToMenu(bool send, bool silent = false);
|
void psSendToMenu(bool send, bool silent = false);
|
||||||
|
|
||||||
QRect psDesktopRect();
|
QRect psDesktopRect();
|
||||||
void psShowOverAll(QWidget *w, bool canFocus = true);
|
|
||||||
void psBringToBack(QWidget *w);
|
|
||||||
|
|
||||||
int psCleanup();
|
int psCleanup();
|
||||||
int psFixPrevious();
|
int psFixPrevious();
|
||||||
|
|
||||||
void psNewVersion();
|
void psNewVersion();
|
||||||
|
|
||||||
void psUpdateOverlayed(QWidget *widget);
|
|
||||||
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include "data/data_peer_values.h"
|
#include "data/data_peer_values.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "dialogs/dialogs_layout.h"
|
#include "dialogs/dialogs_layout.h"
|
||||||
#include "emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
|
|
|
@ -16,10 +16,6 @@ class LocationPoint;
|
||||||
|
|
||||||
namespace Platform {
|
namespace Platform {
|
||||||
|
|
||||||
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CurrentExecutablePath(int argc, char *argv[]);
|
QString CurrentExecutablePath(int argc, char *argv[]);
|
||||||
|
|
||||||
void RemoveQuarantine(const QString &path);
|
void RemoveQuarantine(const QString &path);
|
||||||
|
@ -67,8 +63,6 @@ void psAutoStart(bool start, bool silent = false);
|
||||||
void psSendToMenu(bool send, bool silent = false);
|
void psSendToMenu(bool send, bool silent = false);
|
||||||
|
|
||||||
QRect psDesktopRect();
|
QRect psDesktopRect();
|
||||||
void psShowOverAll(QWidget *w, bool canFocus = true);
|
|
||||||
void psBringToBack(QWidget *w);
|
|
||||||
|
|
||||||
int psCleanup();
|
int psCleanup();
|
||||||
int psFixPrevious();
|
int psFixPrevious();
|
||||||
|
@ -77,8 +71,6 @@ bool psShowOpenWithMenu(int x, int y, const QString &file);
|
||||||
|
|
||||||
void psNewVersion();
|
void psNewVersion();
|
||||||
|
|
||||||
void psUpdateOverlayed(QWidget *widget);
|
|
||||||
|
|
||||||
void psDownloadPathEnableAccess();
|
void psDownloadPathEnableAccess();
|
||||||
QByteArray psDownloadPathBookmark(const QString &path);
|
QByteArray psDownloadPathBookmark(const QString &path);
|
||||||
QByteArray psPathBookmark(const QString &path);
|
QByteArray psPathBookmark(const QString &path);
|
||||||
|
|
|
@ -60,14 +60,6 @@ QRect psDesktopRect() {
|
||||||
return _monitorRect;
|
return _monitorRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psShowOverAll(QWidget *w, bool canFocus) {
|
|
||||||
objc_showOverAll(w->winId(), canFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void psBringToBack(QWidget *w) {
|
|
||||||
objc_bringToBack(w->winId());
|
|
||||||
}
|
|
||||||
|
|
||||||
void psWriteDump() {
|
void psWriteDump() {
|
||||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
double v = objc_appkitVersion();
|
double v = objc_appkitVersion();
|
||||||
|
@ -128,14 +120,6 @@ void finish() {
|
||||||
objc_finish();
|
objc_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
|
|
||||||
#ifdef OS_MAC_OLD
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
|
||||||
p.fillRect(e->rect(), Qt::transparent);
|
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
#endif // OS_MAC_OLD
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CurrentExecutablePath(int argc, char *argv[]) {
|
QString CurrentExecutablePath(int argc, char *argv[]) {
|
||||||
return NS2QString([[NSBundle mainBundle] bundlePath]);
|
return NS2QString([[NSBundle mainBundle] bundlePath]);
|
||||||
}
|
}
|
||||||
|
@ -274,6 +258,10 @@ std::optional<crl::time> LastUserInputTime() {
|
||||||
return (crl::now() - static_cast<crl::time>(idleTime));
|
return (crl::now() - static_cast<crl::time>(idleTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IgnoreApplicationActivationRightNow() {
|
||||||
|
objc_ignoreApplicationActivationRightNow();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
void psNewVersion() {
|
void psNewVersion() {
|
||||||
|
@ -286,9 +274,6 @@ void psAutoStart(bool start, bool silent) {
|
||||||
void psSendToMenu(bool send, bool silent) {
|
void psSendToMenu(bool send, bool silent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void psUpdateOverlayed(QWidget *widget) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void psDownloadPathEnableAccess() {
|
void psDownloadPathEnableAccess() {
|
||||||
objc_downloadPathEnableAccess(Global::DownloadPathBookmark());
|
objc_downloadPathEnableAccess(Global::DownloadPathBookmark());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
bool objc_handleMediaKeyEvent(void *e);
|
bool objc_handleMediaKeyEvent(void *e);
|
||||||
|
|
||||||
bool objc_darkMode();
|
bool objc_darkMode();
|
||||||
void objc_showOverAll(WId winId, bool canFocus = true);
|
|
||||||
void objc_bringToBack(WId winId);
|
|
||||||
|
|
||||||
void objc_debugShowAlert(const QString &str);
|
void objc_debugShowAlert(const QString &str);
|
||||||
void objc_outputDebugString(const QString &str);
|
void objc_outputDebugString(const QString &str);
|
||||||
|
|
|
@ -35,8 +35,6 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kIgnoreActivationTimeoutMs = 500;
|
constexpr auto kIgnoreActivationTimeoutMs = 500;
|
||||||
|
|
||||||
std::optional<bool> ApplicationIsActive;
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
||||||
|
@ -141,7 +139,6 @@ ApplicationDelegate *_sharedDelegate = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) applicationDidBecomeActive:(NSNotification *)aNotification {
|
- (void) applicationDidBecomeActive:(NSNotification *)aNotification {
|
||||||
ApplicationIsActive = true;
|
|
||||||
if (Core::IsAppLaunched() && !_ignoreActivation) {
|
if (Core::IsAppLaunched() && !_ignoreActivation) {
|
||||||
Core::App().handleAppActivated();
|
Core::App().handleAppActivated();
|
||||||
if (auto window = App::wnd()) {
|
if (auto window = App::wnd()) {
|
||||||
|
@ -153,7 +150,6 @@ ApplicationDelegate *_sharedDelegate = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) applicationDidResignActive:(NSNotification *)aNotification {
|
- (void) applicationDidResignActive:(NSNotification *)aNotification {
|
||||||
ApplicationIsActive = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) receiveWakeNote:(NSNotification*)aNotification {
|
- (void) receiveWakeNote:(NSNotification*)aNotification {
|
||||||
|
@ -207,12 +203,6 @@ void SetWatchingMediaKeys(bool watching) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsApplicationActive() {
|
|
||||||
return ApplicationIsActive
|
|
||||||
? *ApplicationIsActive
|
|
||||||
: (static_cast<QApplication*>(QCoreApplication::instance())->activeWindow() != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetApplicationIcon(const QIcon &icon) {
|
void SetApplicationIcon(const QIcon &icon) {
|
||||||
NSImage *image = nil;
|
NSImage *image = nil;
|
||||||
if (!icon.isNull()) {
|
if (!icon.isNull()) {
|
||||||
|
@ -224,46 +214,6 @@ void SetApplicationIcon(const QIcon &icon) {
|
||||||
[image release];
|
[image release];
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitOnTopPanel(QWidget *panel) {
|
|
||||||
Expects(!panel->windowHandle());
|
|
||||||
|
|
||||||
// Force creating windowHandle() without creating the platform window yet.
|
|
||||||
panel->setAttribute(Qt::WA_NativeWindow, true);
|
|
||||||
panel->windowHandle()->setProperty("_td_macNonactivatingPanelMask", QVariant(true));
|
|
||||||
panel->setAttribute(Qt::WA_NativeWindow, false);
|
|
||||||
|
|
||||||
panel->createWinId();
|
|
||||||
|
|
||||||
auto platformWindow = [reinterpret_cast<NSView*>(panel->winId()) window];
|
|
||||||
Assert([platformWindow isKindOfClass:[NSPanel class]]);
|
|
||||||
|
|
||||||
auto platformPanel = static_cast<NSPanel*>(platformWindow);
|
|
||||||
[platformPanel setLevel:NSPopUpMenuWindowLevel];
|
|
||||||
[platformPanel setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces|NSWindowCollectionBehaviorStationary|NSWindowCollectionBehaviorFullScreenAuxiliary|NSWindowCollectionBehaviorIgnoresCycle];
|
|
||||||
[platformPanel setFloatingPanel:YES];
|
|
||||||
[platformPanel setHidesOnDeactivate:NO];
|
|
||||||
|
|
||||||
objc_ignoreApplicationActivationRightNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeInitOnTopPanel(QWidget *panel) {
|
|
||||||
auto platformWindow = [reinterpret_cast<NSView*>(panel->winId()) window];
|
|
||||||
Assert([platformWindow isKindOfClass:[NSPanel class]]);
|
|
||||||
|
|
||||||
auto platformPanel = static_cast<NSPanel*>(platformWindow);
|
|
||||||
auto newBehavior = ([platformPanel collectionBehavior] & (~NSWindowCollectionBehaviorCanJoinAllSpaces)) | NSWindowCollectionBehaviorMoveToActiveSpace;
|
|
||||||
[platformPanel setCollectionBehavior:newBehavior];
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReInitOnTopPanel(QWidget *panel) {
|
|
||||||
auto platformWindow = [reinterpret_cast<NSView*>(panel->winId()) window];
|
|
||||||
Assert([platformWindow isKindOfClass:[NSPanel class]]);
|
|
||||||
|
|
||||||
auto platformPanel = static_cast<NSPanel*>(platformWindow);
|
|
||||||
auto newBehavior = ([platformPanel collectionBehavior] & (~NSWindowCollectionBehaviorMoveToActiveSpace)) | NSWindowCollectionBehaviorCanJoinAllSpaces;
|
|
||||||
[platformPanel setCollectionBehavior:newBehavior];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Platform
|
} // namespace Platform
|
||||||
|
|
||||||
bool objc_darkMode() {
|
bool objc_darkMode() {
|
||||||
|
@ -279,20 +229,6 @@ bool objc_darkMode() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void objc_showOverAll(WId winId, bool canFocus) {
|
|
||||||
NSWindow *wnd = [reinterpret_cast<NSView *>(winId) window];
|
|
||||||
[wnd setLevel:NSPopUpMenuWindowLevel];
|
|
||||||
if (!canFocus) {
|
|
||||||
[wnd setStyleMask:NSUtilityWindowMask | NSNonactivatingPanelMask];
|
|
||||||
[wnd setCollectionBehavior:NSWindowCollectionBehaviorMoveToActiveSpace|NSWindowCollectionBehaviorStationary|NSWindowCollectionBehaviorFullScreenAuxiliary|NSWindowCollectionBehaviorIgnoresCycle];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void objc_bringToBack(WId winId) {
|
|
||||||
NSWindow *wnd = [reinterpret_cast<NSView *>(winId) window];
|
|
||||||
[wnd setLevel:NSModalPanelWindowLevel];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool objc_handleMediaKeyEvent(void *ev) {
|
bool objc_handleMediaKeyEvent(void *ev) {
|
||||||
auto e = reinterpret_cast<NSEvent*>(ev);
|
auto e = reinterpret_cast<NSEvent*>(ev);
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,7 @@ enum class SystemSettingsType {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetWatchingMediaKeys(bool watching);
|
void SetWatchingMediaKeys(bool watching);
|
||||||
bool IsApplicationActive();
|
|
||||||
void SetApplicationIcon(const QIcon &icon);
|
void SetApplicationIcon(const QIcon &icon);
|
||||||
bool TranslucentWindowsSupported(QPoint globalPosition);
|
|
||||||
void StartTranslucentPaint(QPainter &p, QPaintEvent *e);
|
|
||||||
void InitOnTopPanel(QWidget *panel);
|
|
||||||
void DeInitOnTopPanel(QWidget *panel);
|
|
||||||
void ReInitOnTopPanel(QWidget *panel);
|
|
||||||
void RegisterCustomScheme();
|
void RegisterCustomScheme();
|
||||||
PermissionStatus GetPermissionStatus(PermissionType type);
|
PermissionStatus GetPermissionStatus(PermissionType type);
|
||||||
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
|
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
|
||||||
|
@ -45,6 +39,8 @@ bool OpenSystemSettings(SystemSettingsType type);
|
||||||
return LastUserInputTime().has_value();
|
return LastUserInputTime().has_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IgnoreApplicationActivationRightNow();
|
||||||
|
|
||||||
[[nodiscard]] constexpr bool UseMainQueueGeneric();
|
[[nodiscard]] constexpr bool UseMainQueueGeneric();
|
||||||
void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
|
void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "platform/win/windows_event_filter.h"
|
#include "platform/win/windows_event_filter.h"
|
||||||
#include "window/notifications_manager.h"
|
#include "window/notifications_manager.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
#include "base/crc32hash.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "storage/localstorage.h"
|
#include "storage/localstorage.h"
|
||||||
|
@ -661,7 +662,7 @@ int32 MainWindow::screenNameChecksum(const QString &name) const {
|
||||||
} else {
|
} else {
|
||||||
memcpy(buffer, name.toStdWString().data(), sizeof(buffer));
|
memcpy(buffer, name.toStdWString().data(), sizeof(buffer));
|
||||||
}
|
}
|
||||||
return hashCrc32(buffer, sizeof(buffer));
|
return base::crc32(buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::psRefreshTaskbarIcon() {
|
void MainWindow::psRefreshTaskbarIcon() {
|
||||||
|
|
|
@ -201,12 +201,6 @@ QRect psDesktopRect() {
|
||||||
return _monitorRect;
|
return _monitorRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psShowOverAll(QWidget *w, bool canFocus) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void psBringToBack(QWidget *w) {
|
|
||||||
}
|
|
||||||
|
|
||||||
int psCleanup() {
|
int psCleanup() {
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
|
@ -308,10 +302,6 @@ void start() {
|
||||||
void finish() {
|
void finish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsApplicationActive() {
|
|
||||||
return QApplication::activeWindow() != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetApplicationIcon(const QIcon &icon) {
|
void SetApplicationIcon(const QIcon &icon) {
|
||||||
QApplication::setWindowIcon(icon);
|
QApplication::setWindowIcon(icon);
|
||||||
}
|
}
|
||||||
|
@ -572,17 +562,6 @@ void psSendToMenu(bool send, bool silent) {
|
||||||
_manageAppLnk(send, silent, CSIDL_SENDTO, L"-sendpath", L"Telegram send to link.\nYou can disable send to menu item in Telegram settings.");
|
_manageAppLnk(send, silent, CSIDL_SENDTO, L"-sendpath", L"Telegram send to link.\nYou can disable send to menu item in Telegram settings.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void psUpdateOverlayed(QWidget *widget) {
|
|
||||||
bool wm = widget->testAttribute(Qt::WA_Mapped), wv = widget->testAttribute(Qt::WA_WState_Visible);
|
|
||||||
if (!wm) widget->setAttribute(Qt::WA_Mapped, true);
|
|
||||||
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, true);
|
|
||||||
widget->update();
|
|
||||||
QEvent e(QEvent::UpdateRequest);
|
|
||||||
QGuiApplication::sendEvent(widget, &e);
|
|
||||||
if (!wm) widget->setAttribute(Qt::WA_Mapped, false);
|
|
||||||
if (!wv) widget->setAttribute(Qt::WA_WState_Visible, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void psWriteDump() {
|
void psWriteDump() {
|
||||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||||
PROCESS_MEMORY_COUNTERS data = { 0 };
|
PROCESS_MEMORY_COUNTERS data = { 0 };
|
||||||
|
|
|
@ -19,26 +19,11 @@ namespace Platform {
|
||||||
inline void SetWatchingMediaKeys(bool watching) {
|
inline void SetWatchingMediaKeys(bool watching) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsApplicationActive();
|
|
||||||
|
|
||||||
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void StartTranslucentPaint(QPainter &p, QPaintEvent *e) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void InitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DeInitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ReInitOnTopPanel(QWidget *panel) {
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CurrentExecutablePath(int argc, char *argv[]);
|
QString CurrentExecutablePath(int argc, char *argv[]);
|
||||||
|
|
||||||
|
inline void IgnoreApplicationActivationRightNow() {
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr bool UseMainQueueGeneric() {
|
inline constexpr bool UseMainQueueGeneric() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -74,15 +59,12 @@ void psAutoStart(bool start, bool silent = false);
|
||||||
void psSendToMenu(bool send, bool silent = false);
|
void psSendToMenu(bool send, bool silent = false);
|
||||||
|
|
||||||
QRect psDesktopRect();
|
QRect psDesktopRect();
|
||||||
void psShowOverAll(QWidget *w, bool canFocus = true);
|
|
||||||
void psBringToBack(QWidget *w);
|
|
||||||
|
|
||||||
int psCleanup();
|
int psCleanup();
|
||||||
int psFixPrevious();
|
int psFixPrevious();
|
||||||
|
|
||||||
void psNewVersion();
|
void psNewVersion();
|
||||||
|
|
||||||
void psUpdateOverlayed(QWidget *widget);
|
|
||||||
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "platform/win/windows_dlls.h"
|
#include "platform/win/windows_dlls.h"
|
||||||
#include "core/sandbox.h"
|
#include "core/sandbox.h"
|
||||||
|
#include "ui/inactive_press.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
|
@ -113,7 +114,7 @@ bool EventFilter::mainWindowEvent(
|
||||||
|
|
||||||
case WM_ACTIVATE: {
|
case WM_ACTIVATE: {
|
||||||
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
||||||
_window->setInactivePress(true);
|
Ui::MarkInactivePress(_window, true);
|
||||||
}
|
}
|
||||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||||
_window->shadowsActivate();
|
_window->shadowsActivate();
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue