mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-11 08:48:14 +00:00
Move many widget classes to lib_ui.
This commit is contained in:
parent
dda587a2fc
commit
849deb57e2
@ -72,8 +72,11 @@ linkCropLimit: 360px;
|
||||
linkFont: normalFont;
|
||||
linkOverFont: font(fsize underline);
|
||||
|
||||
dateRadius: 6px;
|
||||
buttonRadius: 3px;
|
||||
roundRadiusLarge: 6px;
|
||||
roundRadiusSmall: 3px;
|
||||
|
||||
dateRadius: roundRadiusLarge;
|
||||
buttonRadius: roundRadiusSmall;
|
||||
|
||||
setLittleSkip: 9px;
|
||||
|
||||
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "api/api_sending.h"
|
||||
|
||||
#include "api/api_text_entities.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_photo.h"
|
||||
@ -73,12 +74,12 @@ void SendExistingMedia(
|
||||
|
||||
auto caption = TextWithEntities{
|
||||
message.textWithTags.text,
|
||||
ConvertTextTagsToEntities(message.textWithTags.tags)
|
||||
TextUtilities::ConvertTextTagsToEntities(message.textWithTags.tags)
|
||||
};
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
auto sentEntities = EntitiesToMTP(
|
||||
caption.entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
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 "api/api_text_entities.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_web_page.h"
|
||||
@ -2562,9 +2563,9 @@ void ApiWrap::saveDraftsToCloud() {
|
||||
if (!textWithTags.tags.isEmpty()) {
|
||||
flags |= MTPmessages_SaveDraft::Flag::f_entities;
|
||||
}
|
||||
auto entities = TextUtilities::EntitiesToMTP(
|
||||
ConvertTextTagsToEntities(textWithTags.tags),
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
auto entities = Api::EntitiesToMTP(
|
||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags),
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
const auto draftText = textWithTags.text;
|
||||
history->setSentDraftText(draftText);
|
||||
@ -4830,9 +4831,9 @@ void ApiWrap::editUploadedFile(
|
||||
return;
|
||||
}
|
||||
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
auto sentEntities = Api::EntitiesToMTP(
|
||||
item->originalText().entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
auto flagsEditMsg = MTPmessages_EditMessage::Flag::f_message | 0;
|
||||
flagsEditMsg |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
||||
@ -4934,7 +4935,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
auto sending = TextWithEntities();
|
||||
auto left = TextWithEntities {
|
||||
textWithTags.text,
|
||||
ConvertTextTagsToEntities(textWithTags.tags)
|
||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
||||
};
|
||||
auto prepareFlags = Ui::ItemTextOptions(
|
||||
history,
|
||||
@ -4988,8 +4989,10 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
|
||||
if (silentPost) {
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_silent;
|
||||
}
|
||||
auto localEntities = TextUtilities::EntitiesToMTP(sending.entities);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(sending.entities, TextUtilities::ConvertOption::SkipLocal);
|
||||
auto localEntities = Api::EntitiesToMTP(sending.entities);
|
||||
auto sentEntities = Api::EntitiesToMTP(
|
||||
sending.entities,
|
||||
Api::ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
sendFlags |= MTPmessages_SendMessage::Flag::f_entities;
|
||||
}
|
||||
@ -5274,9 +5277,9 @@ void ApiWrap::sendMediaWithRandomId(
|
||||
|
||||
auto caption = item->originalText();
|
||||
TextUtilities::Trim(caption);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
auto sentEntities = Api::EntitiesToMTP(
|
||||
caption.entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
Api::ConvertOption::SkipLocal);
|
||||
|
||||
const auto flags = MTPmessages_SendMedia::Flags(0)
|
||||
| (replyTo
|
||||
|
@ -63,8 +63,6 @@ namespace {
|
||||
*pressedLinkItem = nullptr,
|
||||
*mousedItem = nullptr;
|
||||
|
||||
style::font monofont;
|
||||
|
||||
struct CornersPixmaps {
|
||||
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() {
|
||||
QImage mask[4];
|
||||
prepareCorners(SmallMaskCorners, st::buttonRadius, QColor(255, 255, 255), nullptr, mask);
|
||||
@ -204,16 +194,6 @@ namespace App {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
using Update = Window::Theme::BackgroundUpdate;
|
||||
@ -293,10 +273,6 @@ namespace App {
|
||||
mousedItem(nullptr);
|
||||
}
|
||||
|
||||
const style::font &monofont() {
|
||||
return ::monofont;
|
||||
}
|
||||
|
||||
void quit() {
|
||||
if (quitting()) {
|
||||
return;
|
||||
@ -451,15 +427,6 @@ namespace App {
|
||||
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) {
|
||||
auto cornerWidth = corner.p[0].width() / cIntRetinaFactor();
|
||||
auto cornerHeight = corner.p[0].height() / cIntRetinaFactor();
|
||||
|
@ -81,8 +81,6 @@ namespace App {
|
||||
HistoryView::Element *mousedItem();
|
||||
void clearMousedItems();
|
||||
|
||||
const style::font &monofont();
|
||||
|
||||
void initMedia();
|
||||
void deinitMedia();
|
||||
|
||||
@ -106,7 +104,6 @@ namespace App {
|
||||
void complexOverlayRect(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);
|
||||
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);
|
||||
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
// Smart pointer for QObject*, has move semantics, destroys object if it doesn't have a parent.
|
||||
template <typename Object>
|
||||
class object_ptr {
|
||||
|
@ -524,6 +524,17 @@ inline void AddRandomSeed(bytes::const_span data) {
|
||||
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(
|
||||
bytes::const_span password,
|
||||
bytes::const_span salt,
|
||||
|
@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QRegularExpression>
|
||||
|
||||
namespace qthelp {
|
||||
|
||||
const QRegularExpression &RegExpDomain();
|
||||
|
@ -108,8 +108,8 @@ void Timer::timerEvent(QTimerEvent *e) {
|
||||
cancel();
|
||||
}
|
||||
|
||||
if (_callback) {
|
||||
_callback();
|
||||
if (const auto onstack = _callback) {
|
||||
onstack();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QPointer>
|
||||
|
||||
namespace base {
|
||||
|
||||
template <typename T>
|
||||
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/painter.h"
|
||||
#include "base/timer.h"
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
@ -135,7 +136,7 @@ void BoxContent::onDraggingScrollDelta(int delta) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -276,7 +277,6 @@ AbstractBox::AbstractBox(
|
||||
: LayerWidget(layer)
|
||||
, _layer(layer)
|
||||
, _content(std::move(content)) {
|
||||
subscribe(Lang::Current().updated(), [=] { refreshLang(); });
|
||||
_content->setParent(this);
|
||||
_content->setDelegate(this);
|
||||
|
||||
@ -398,10 +398,6 @@ bool AbstractBox::closeByOutsideClick() const {
|
||||
return _closeByOutsideClick;
|
||||
}
|
||||
|
||||
void AbstractBox::refreshLang() {
|
||||
InvokeQueued(this, [this] { updateButtonsPositions(); });
|
||||
}
|
||||
|
||||
bool AbstractBox::hasTitle() const {
|
||||
return (_title != nullptr) || !_additionalTitle.current().isEmpty();
|
||||
}
|
||||
@ -464,7 +460,10 @@ QPointer<Ui::RoundButton> AbstractBox::addButton(
|
||||
auto result = QPointer<Ui::RoundButton>(_buttons.back());
|
||||
result->setClickedCallback(std::move(clickCallback));
|
||||
result->show();
|
||||
updateButtonsPositions();
|
||||
result->widthValue(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateButtonsPositions();
|
||||
}, result->lifetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -476,7 +475,10 @@ QPointer<Ui::RoundButton> AbstractBox::addLeftButton(
|
||||
auto result = QPointer<Ui::RoundButton>(_leftButton);
|
||||
result->setClickedCallback(std::move(clickCallback));
|
||||
result->show();
|
||||
updateButtonsPositions();
|
||||
result->widthValue(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateButtonsPositions();
|
||||
}, result->lifetime());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "base/unique_qptr.h"
|
||||
#include "base/flags.h"
|
||||
#include "ui/effects/animation_value.h"
|
||||
#include "ui/text/text_entity.h"
|
||||
#include "ui/rp_widget.h"
|
||||
|
||||
class Painter;
|
||||
|
||||
namespace style {
|
||||
struct RoundButton;
|
||||
struct IconButton;
|
||||
@ -77,7 +80,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class BoxContent : public Ui::RpWidget, protected base::Subscriber {
|
||||
class BoxContent : public Ui::RpWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -270,10 +273,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class AbstractBox
|
||||
: public Window::LayerWidget
|
||||
, public BoxContentDelegate
|
||||
, protected base::Subscriber {
|
||||
class AbstractBox : public Window::LayerWidget, public BoxContentDelegate {
|
||||
public:
|
||||
AbstractBox(
|
||||
not_null<Window::LayerStackWidget*> layer,
|
||||
@ -345,7 +345,6 @@ private:
|
||||
|
||||
void paintAdditionalTitle(Painter &p);
|
||||
void updateTitlePosition();
|
||||
void refreshLang();
|
||||
|
||||
[[nodiscard]] bool hasTitle() const;
|
||||
[[nodiscard]] int titleHeight() const;
|
||||
|
@ -25,10 +25,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "window/window_session_controller.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/special_fields.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "ui/unread_badge.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:
|
||||
SetupChannelBox(
|
||||
QWidget*,
|
||||
@ -234,7 +237,10 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class RevokePublicLinkBox : public BoxContent, public RPCSender {
|
||||
class RevokePublicLinkBox
|
||||
: public BoxContent
|
||||
, public RPCSender
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
RevokePublicLinkBox(
|
||||
QWidget*,
|
||||
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "apiwrap.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "boxes/background_preview_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "app.h"
|
||||
|
@ -25,7 +25,8 @@ class Checkbox;
|
||||
|
||||
class BackgroundPreviewBox
|
||||
: public BoxContent
|
||||
, private HistoryView::SimpleElementDelegate {
|
||||
, private HistoryView::SimpleElementDelegate
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
BackgroundPreviewBox(
|
||||
QWidget*,
|
||||
|
@ -17,7 +17,7 @@ namespace Ui {
|
||||
class IconButton;
|
||||
} // namespace Ui
|
||||
|
||||
class CalendarBox : public BoxContent {
|
||||
class CalendarBox : public BoxContent, private base::Subscriber {
|
||||
public:
|
||||
CalendarBox(
|
||||
QWidget*,
|
||||
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/special_fields.h"
|
||||
#include "boxes/confirm_phone_box.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "main/main_session.h"
|
||||
|
@ -254,8 +254,9 @@ void ConfirmBox::mouseReleaseEvent(QMouseEvent *e) {
|
||||
_lastMousePos = e->globalPos();
|
||||
updateHover();
|
||||
if (const auto activated = ClickHandler::unpressed()) {
|
||||
const auto guard = window();
|
||||
Ui::hideLayer();
|
||||
App::activateClickHandler(activated, e->button());
|
||||
ActivateClickHandler(guard, activated, e->button());
|
||||
return;
|
||||
}
|
||||
BoxContent::mouseReleaseEvent(e);
|
||||
|
@ -95,7 +95,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class MaxInviteBox : public BoxContent {
|
||||
class MaxInviteBox : public BoxContent, private base::Subscriber {
|
||||
public:
|
||||
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:
|
||||
ConfirmInviteBox(
|
||||
QWidget*,
|
||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/edit_caption_box.h"
|
||||
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "main/main_session.h"
|
||||
#include "chat_helpers/emoji_suggestions_widget.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_user.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.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_history.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/text_options.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "confirm_box.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
@ -898,7 +901,7 @@ void EditCaptionBox::save() {
|
||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||
auto sending = TextWithEntities{
|
||||
textWithTags.text,
|
||||
ConvertTextTagsToEntities(textWithTags.tags)
|
||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
||||
};
|
||||
const auto prepareFlags = Ui::ItemTextOptions(
|
||||
item->history(),
|
||||
@ -906,9 +909,9 @@ void EditCaptionBox::save() {
|
||||
TextUtilities::PrepareForSending(sending, prepareFlags);
|
||||
TextUtilities::Trim(sending);
|
||||
|
||||
const auto sentEntities = TextUtilities::EntitiesToMTP(
|
||||
const auto sentEntities = Api::EntitiesToMTP(
|
||||
sending.entities,
|
||||
TextUtilities::ConvertOption::SkipLocal);
|
||||
Api::ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
flags |= MTPmessages_EditMessage::Flag::f_entities;
|
||||
}
|
||||
@ -917,7 +920,7 @@ void EditCaptionBox::save() {
|
||||
const auto textWithTags = _field->getTextWithAppliedMarkdown();
|
||||
auto sending = TextWithEntities{
|
||||
textWithTags.text,
|
||||
ConvertTextTagsToEntities(textWithTags.tags)
|
||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags)
|
||||
};
|
||||
item->setText(sending);
|
||||
|
||||
|
@ -35,7 +35,10 @@ namespace Window {
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
class EditCaptionBox : public BoxContent, public RPCSender {
|
||||
class EditCaptionBox
|
||||
: public BoxContent
|
||||
, public RPCSender
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
EditCaptionBox(
|
||||
QWidget*,
|
||||
|
@ -9,7 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "boxes/abstract_box.h"
|
||||
|
||||
class EditColorBox : public BoxContent {
|
||||
class EditColorBox : public BoxContent, private base::Subscriber {
|
||||
public:
|
||||
enum class Mode {
|
||||
RGBA,
|
||||
|
@ -36,6 +36,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/padding_wrap.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/special_fields.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include <rpl/flatten_latest.h>
|
||||
|
||||
|
@ -441,7 +441,7 @@ void StickerSetBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
const auto index = stickerFromGlobalPos(e->globalPos());
|
||||
if (index >= 0 && index < _pack.size() && !isMasksSet()) {
|
||||
const auto sticker = _pack[index];
|
||||
Core::App().postponeCall(crl::guard(App::main(), [=] {
|
||||
Ui::PostponeCall(crl::guard(App::main(), [=] {
|
||||
if (App::main()->onSendSticker(sticker)) {
|
||||
Ui::hideSettingsAndLayer();
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mtproto/sender.h"
|
||||
#include "chat_helpers/stickers.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/special_fields.h"
|
||||
|
||||
class ConfirmBox;
|
||||
|
||||
@ -32,7 +32,10 @@ namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
||||
class StickersBox : public BoxContent, public RPCSender {
|
||||
class StickersBox final
|
||||
: public BoxContent
|
||||
, public RPCSender
|
||||
, private base::Subscriber {
|
||||
public:
|
||||
enum class Section {
|
||||
Installed,
|
||||
|
@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/special_fields.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "core/application.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_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_file_origin.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/labels.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "core/application.h"
|
||||
@ -31,6 +31,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "window/main_window.h"
|
||||
#include "layout.h"
|
||||
#include "app.h"
|
||||
#include "styles/style_calls.h"
|
||||
#include "styles/style_history.h"
|
||||
|
||||
#include <QtWidgets/QDesktopWidget>
|
||||
#include <QtWidgets/QApplication>
|
||||
@ -440,7 +442,7 @@ void Panel::initLayout() {
|
||||
});
|
||||
createDefaultCacheImage();
|
||||
|
||||
Platform::InitOnTopPanel(this);
|
||||
Ui::Platform::InitOnTopPanel(this);
|
||||
}
|
||||
|
||||
void Panel::toggleOpacityAnimation(bool visible) {
|
||||
@ -592,7 +594,7 @@ bool Panel::isGoodUserPhoto(PhotoData *photo) {
|
||||
|
||||
void Panel::initGeometry() {
|
||||
auto center = Core::App().getPointForCallPanelCenter();
|
||||
_useTransparency = Platform::TranslucentWindowsSupported(center);
|
||||
_useTransparency = Ui::Platform::TranslucentWindowsSupported(center);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);
|
||||
_padding = _useTransparency ? st::callShadow.extend : style::margins(st::lineWidth, st::lineWidth, st::lineWidth, st::lineWidth);
|
||||
_contentTop = _padding.top() + st::callWidth;
|
||||
@ -704,7 +706,7 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||
finishAnimating();
|
||||
if (!_call || isHidden()) return;
|
||||
} else {
|
||||
Platform::StartTranslucentPaint(p, e);
|
||||
Ui::Platform::StartTranslucentPaint(p, e);
|
||||
p.setOpacity(opacity);
|
||||
|
||||
PainterHighQualityEnabler hq(p);
|
||||
@ -717,7 +719,7 @@ void Panel::paintEvent(QPaintEvent *e) {
|
||||
}
|
||||
|
||||
if (_useTransparency) {
|
||||
Platform::StartTranslucentPaint(p, e);
|
||||
Ui::Platform::StartTranslucentPaint(p, e);
|
||||
p.drawPixmapLeft(0, 0, width(), _cache);
|
||||
} else {
|
||||
p.drawPixmapLeft(_padding.left(), _padding.top(), width(), _userPhoto);
|
||||
@ -864,9 +866,9 @@ void Panel::stateChanged(State state) {
|
||||
if (windowHandle()) {
|
||||
// First stateChanged() is called before the first Platform::InitOnTopPanel(this).
|
||||
if ((state == State::Starting) || (state == State::WaitingIncoming)) {
|
||||
Platform::ReInitOnTopPanel(this);
|
||||
Ui::Platform::ReInitOnTopPanel(this);
|
||||
} else {
|
||||
Platform::DeInitOnTopPanel(this);
|
||||
Ui::Platform::DeInitOnTopPanel(this);
|
||||
}
|
||||
}
|
||||
if (state == State::Established) {
|
||||
|
@ -135,7 +135,7 @@ void BotKeyboard::mouseReleaseEvent(QMouseEvent *e) {
|
||||
updateSelected();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool BotKeyboard::tooltipWindowActive() const {
|
||||
return Ui::InFocusChain(window());
|
||||
}
|
||||
|
||||
QString BotKeyboard::tooltipText() const {
|
||||
if (ClickHandlerPtr lnk = ClickHandler::getActive()) {
|
||||
return lnk->tooltip();
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
// AbstractTooltipShower interface
|
||||
QString tooltipText() const override;
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
// ClickHandlerHost interface
|
||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||
|
@ -769,6 +769,10 @@ QPoint EmojiListWidget::tooltipPos() const {
|
||||
return _lastMousePos;
|
||||
}
|
||||
|
||||
bool EmojiListWidget::tooltipWindowActive() const {
|
||||
return Ui::InFocusChain(window());
|
||||
}
|
||||
|
||||
TabbedSelector::InnerFooter *EmojiListWidget::getFooter() const {
|
||||
return _footer;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
// Ui::AbstractTooltipShower interface.
|
||||
QString tooltipText() const override;
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
rpl::producer<EmojiPtr> chosen() const;
|
||||
|
||||
|
@ -356,7 +356,7 @@ void GifsListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
int row = _selected / MatrixRowShift, column = _selected % MatrixRowShift;
|
||||
selectInlineResult(row, column);
|
||||
} 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;
|
||||
|
||||
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.
|
||||
class FieldTagMimeProcessor : public Ui::InputField::TagMimeProcessor {
|
||||
public:
|
||||
QString mimeTagFromTag(const QString &tagId) override {
|
||||
return ConvertTagToMimeTag(tagId);
|
||||
}
|
||||
|
||||
QString tagFromMimeTag(const QString &mimeTag) override {
|
||||
if (IsMentionLink(mimeTag)) {
|
||||
if (TextUtilities::IsMentionLink(mimeTag)) {
|
||||
auto match = QRegularExpression(":(\\d+)$").match(mimeTag);
|
||||
if (!match.hasMatch()
|
||||
|| match.capturedRef(1).toInt() != Auth().userId()) {
|
||||
@ -216,135 +207,20 @@ TextWithEntities StripSupportHashtag(TextWithEntities &&text) {
|
||||
|
||||
} // namespace
|
||||
|
||||
QString ConvertTagToMimeTag(const QString &tagId) {
|
||||
if (IsMentionLink(tagId)) {
|
||||
return tagId + ':' + QString::number(Auth().userId());
|
||||
}
|
||||
return tagId;
|
||||
}
|
||||
|
||||
QString PrepareMentionTag(not_null<UserData*> user) {
|
||||
return kMentionTagStart
|
||||
return TextUtilities::kMentionTagStart
|
||||
+ QString::number(user->bareId())
|
||||
+ '.'
|
||||
+ 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) {
|
||||
const auto original = item->history()->session().supportMode()
|
||||
? StripSupportHashtag(item->originalText())
|
||||
: item->originalText();
|
||||
return TextWithTags{
|
||||
original.text,
|
||||
ConvertEntitiesToTextTags(original.entities)
|
||||
TextUtilities::ConvertEntitiesToTextTags(original.entities)
|
||||
};
|
||||
}
|
||||
|
||||
@ -363,7 +239,7 @@ Fn<bool(
|
||||
EditLinkAction action) {
|
||||
if (action == EditLinkAction::Check) {
|
||||
return Ui::InputField::IsValidMarkdownLink(link)
|
||||
&& !IsMentionLink(link);
|
||||
&& !TextUtilities::IsMentionLink(link);
|
||||
}
|
||||
Ui::show(Box<EditLinkBox>(session, text, link, [=](
|
||||
const QString &text,
|
||||
@ -617,7 +493,7 @@ void MessageLinksParser::parse() {
|
||||
Expects(tag != tagsEnd);
|
||||
|
||||
if (Ui::InputField::IsValidMarkdownLink(tag->id)
|
||||
&& !IsMentionLink(tag->id)) {
|
||||
&& !TextUtilities::IsMentionLink(tag->id)) {
|
||||
ranges.push_back({ tag->offset, tag->length, tag->id });
|
||||
}
|
||||
++tag;
|
||||
|
@ -21,16 +21,7 @@ namespace Window {
|
||||
class SessionController;
|
||||
} // namespace Window
|
||||
|
||||
QString ConvertTagToMimeTag(const QString &tagId);
|
||||
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);
|
||||
|
||||
Fn<bool(
|
||||
|
@ -323,8 +323,7 @@ void TabbedPanel::startShowAnimation() {
|
||||
_showAnimation = std::make_unique<Ui::PanelAnimation>(st::emojiPanAnimation, Ui::PanelAnimation::Origin::BottomRight);
|
||||
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
||||
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
||||
auto corners = App::cornersMask(ImageRoundRadius::Small);
|
||||
_showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]);
|
||||
_showAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||
_showAnimation->start();
|
||||
}
|
||||
hideChildren();
|
||||
|
@ -813,8 +813,7 @@ void TabbedSelector::switchTab() {
|
||||
_slideAnimation = std::make_unique<SlideAnimation>();
|
||||
auto slidingRect = QRect(0, _scroll->y() * cIntRetinaFactor(), width() * cIntRetinaFactor(), (height() - _scroll->y()) * cIntRetinaFactor());
|
||||
_slideAnimation->setFinalImages(direction, std::move(wasCache), std::move(nowCache), slidingRect, wasSectionIcons);
|
||||
auto corners = App::cornersMask(ImageRoundRadius::Small);
|
||||
_slideAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]);
|
||||
_slideAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||
_slideAnimation->start();
|
||||
|
||||
hideForSliding();
|
||||
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "codegen/style/generator.h"
|
||||
|
||||
#include "base/crc32hash.h"
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
@ -33,54 +35,6 @@ const auto kMustBeContrast = std::map<QString, QString>{
|
||||
{ "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) {
|
||||
if (ch < 10) {
|
||||
return '0' + ch;
|
||||
@ -844,7 +798,7 @@ void palette::finalize() {\n\
|
||||
return false;
|
||||
}
|
||||
auto count = indexInPalette;
|
||||
auto checksum = hashCrc32(checksumString.constData(), checksumString.size());
|
||||
auto checksum = base::crc32(checksumString.constData(), checksumString.size());
|
||||
|
||||
source_->stream() << "\n\n";
|
||||
for (const auto &[over, under] : kMustBeContrast) {
|
||||
|
@ -22,11 +22,6 @@ enum {
|
||||
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
|
||||
|
||||
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
|
||||
LocalEncryptNoPwdIterCount = 4, // key derivation iteration count without pwd (not secure anyway)
|
||||
LocalEncryptSaltSize = 32, // 256 bit
|
||||
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "core/sandbox.h"
|
||||
#include "core/local_url_handlers.h"
|
||||
#include "core/launcher.h"
|
||||
#include "core/core_ui_integration.h"
|
||||
#include "chat_helpers/emoji_keywords.h"
|
||||
#include "storage/localstorage.h"
|
||||
#include "platform/platform_specific.h"
|
||||
@ -80,6 +81,7 @@ Application *Application::Instance = nullptr;
|
||||
|
||||
struct Application::Private {
|
||||
base::Timer quitTimer;
|
||||
UiIntegration uiIntegration;
|
||||
};
|
||||
|
||||
Application::Application(not_null<Launcher*> launcher)
|
||||
@ -98,6 +100,8 @@ Application::Application(not_null<Launcher*> launcher)
|
||||
Expects(!_logo.isNull());
|
||||
Expects(!_logoNoMargin.isNull());
|
||||
|
||||
Ui::Integration::Set(&_private->uiIntegration);
|
||||
|
||||
activeAccount().sessionChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
if (_mediaView) {
|
||||
@ -778,25 +782,6 @@ void Application::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() {
|
||||
auto prevents = false;
|
||||
if (IsAppLaunched()
|
||||
@ -871,19 +856,3 @@ Application &App() {
|
||||
}
|
||||
|
||||
} // 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.
|
||||
void postponeCall(FnMut<void()> &&callable);
|
||||
void refreshGlobalProxy();
|
||||
void activateWindowDelayed(not_null<QWidget*> widget);
|
||||
void pauseDelayedWindowActivations();
|
||||
void resumeDelayedWindowActivations();
|
||||
void preventWindowActivation();
|
||||
|
||||
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 "core/application.h"
|
||||
#include "core/local_url_handlers.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "mainwidget.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 "base/qthelp_regex.h"
|
||||
#include "base/qthelp_url.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_session.h"
|
||||
#include "facades.h"
|
||||
@ -38,63 +34,6 @@ bool UrlRequiresConfirmation(const QUrl &url) {
|
||||
|
||||
} // 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) {
|
||||
url = Core::TryConvertUrlToLocal(url);
|
||||
if (Core::InternalPassportLink(url)) {
|
||||
|
@ -7,74 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "core/click_handler.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;
|
||||
|
||||
};
|
||||
#include "ui/basic_click_handlers.h"
|
||||
|
||||
class HiddenUrlClickHandler : public UrlClickHandler {
|
||||
public:
|
||||
@ -98,6 +31,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class UserData;
|
||||
class BotGameUrlClickHandler : public UrlClickHandler {
|
||||
public:
|
||||
BotGameUrlClickHandler(UserData *bot, QString url)
|
||||
@ -208,7 +142,6 @@ private:
|
||||
};
|
||||
|
||||
class PeerData;
|
||||
class UserData;
|
||||
class BotCommandClickHandler : public TextClickHandler {
|
||||
public:
|
||||
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 "core/application.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "ui/delayed_activation.h"
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QtWidgets/QFileDialog>
|
||||
@ -26,7 +27,7 @@ bool filedialogGetSaveFile(
|
||||
const QString &initialPath) {
|
||||
QStringList files;
|
||||
QByteArray remoteContent;
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
bool result = Platform::FileDialog::Get(
|
||||
parent,
|
||||
files,
|
||||
@ -119,7 +120,7 @@ namespace File {
|
||||
|
||||
void OpenEmailLink(const QString &email) {
|
||||
crl::on_main([=] {
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
Platform::File::UnsafeOpenEmailLink(email);
|
||||
});
|
||||
}
|
||||
@ -127,7 +128,7 @@ void OpenEmailLink(const QString &email) {
|
||||
void OpenWith(const QString &filepath, QPoint menuPosition) {
|
||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||
if (!Platform::File::UnsafeShowOpenWithDropdown(filepath, menuPosition)) {
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
if (!Platform::File::UnsafeShowOpenWith(filepath)) {
|
||||
Platform::File::UnsafeLaunch(filepath);
|
||||
}
|
||||
@ -137,14 +138,14 @@ void OpenWith(const QString &filepath, QPoint menuPosition) {
|
||||
|
||||
void Launch(const QString &filepath) {
|
||||
crl::on_main([=] {
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
Platform::File::UnsafeLaunch(filepath);
|
||||
});
|
||||
}
|
||||
|
||||
void ShowInFolder(const QString &filepath) {
|
||||
crl::on_main([=] {
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
Platform::File::UnsafeShowInFolder(filepath);
|
||||
});
|
||||
}
|
||||
@ -231,7 +232,7 @@ void GetOpenPath(
|
||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||
auto files = QStringList();
|
||||
auto remoteContent = QByteArray();
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
const auto success = Platform::FileDialog::Get(
|
||||
parent,
|
||||
files,
|
||||
@ -265,7 +266,7 @@ void GetOpenPaths(
|
||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||
auto files = QStringList();
|
||||
auto remoteContent = QByteArray();
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
const auto success = Platform::FileDialog::Get(
|
||||
parent,
|
||||
files,
|
||||
@ -314,7 +315,7 @@ void GetFolder(
|
||||
InvokeQueued(QCoreApplication::instance(), [=] {
|
||||
auto files = QStringList();
|
||||
auto remoteContent = QByteArray();
|
||||
Core::App().preventWindowActivation();
|
||||
Ui::PreventDelayedActivation();
|
||||
const auto success = Platform::FileDialog::Get(
|
||||
parent,
|
||||
files,
|
||||
|
@ -323,7 +323,7 @@ QStringList Launcher::readArguments(int argc, char *argv[]) const {
|
||||
auto result = QStringList();
|
||||
result.reserve(argc);
|
||||
for (auto i = 0; i != argc; ++i) {
|
||||
result.push_back(fromUtf8Safe(argv[i]));
|
||||
result.push_back(base::FromUtf8Safe(argv[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "core/local_url_handlers.h"
|
||||
|
||||
#include "api/api_text_entities.h"
|
||||
#include "base/qthelp_regex.h"
|
||||
#include "base/qthelp_url.h"
|
||||
#include "lang/lang_cloud_manager.h"
|
||||
@ -337,8 +338,7 @@ bool HandleUnknown(
|
||||
const auto callback = [=](const MTPDhelp_deepLinkInfo &result) {
|
||||
const auto text = TextWithEntities{
|
||||
qs(result.vmessage()),
|
||||
TextUtilities::EntitiesFromMTP(
|
||||
result.ventities().value_or_empty())
|
||||
Api::EntitiesFromMTP(result.ventities().value_or_empty())
|
||||
};
|
||||
if (result.is_update_app()) {
|
||||
const auto box = std::make_shared<QPointer<BoxContent>>();
|
||||
|
@ -542,30 +542,6 @@ bool Sandbox::nativeEventFilter(
|
||||
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 {
|
||||
return _widgetUpdateRequests.events();
|
||||
}
|
||||
|
@ -48,10 +48,6 @@ public:
|
||||
return callable();
|
||||
}
|
||||
|
||||
void activateWindowDelayed(not_null<QWidget*> widget);
|
||||
void pauseDelayedWindowActivations();
|
||||
void resumeDelayedWindowActivations();
|
||||
|
||||
rpl::producer<> widgetUpdateRequests() const;
|
||||
|
||||
ProxyData sandboxProxy() const;
|
||||
@ -110,9 +106,6 @@ private:
|
||||
std::vector<int> _previousLoopNestingLevels;
|
||||
std::vector<PostponedCall> _postponedCalls;
|
||||
|
||||
QPointer<QWidget> _windowForDelayedActivation;
|
||||
bool _delayedActivationsPaused = false;
|
||||
|
||||
not_null<Launcher*> _launcher;
|
||||
std::unique_ptr<Application> _application;
|
||||
|
||||
|
@ -438,50 +438,6 @@ int GetNextRequestId() {
|
||||
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) {
|
||||
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
|
||||
inline std::array<char, 20> hashSha1(const void *data, int size) {
|
||||
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);
|
||||
|
||||
template <typename T>
|
||||
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "data/data_drafts.h"
|
||||
|
||||
#include "api/api_text_entities.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "chat_helpers/message_field.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 textWithTags = TextWithTags {
|
||||
qs(draft.vmessage()),
|
||||
ConvertEntitiesToTextTags(
|
||||
TextUtilities::EntitiesFromMTP(
|
||||
draft.ventities().value_or_empty()))
|
||||
TextUtilities::ConvertEntitiesToTextTags(
|
||||
Api::EntitiesFromMTP(draft.ventities().value_or_empty()))
|
||||
};
|
||||
auto replyTo = draft.vreply_to_msg_id().value_or_empty();
|
||||
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_folder.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "base/crc32hash.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "observer_peer.h"
|
||||
#include "apiwrap.h"
|
||||
@ -69,7 +71,7 @@ style::color PeerUserpicColor(PeerId peerId) {
|
||||
PeerId FakePeerIdForJustName(const QString &name) {
|
||||
return peerFromUser(name.isEmpty()
|
||||
? 777
|
||||
: hashCrc32(name.constData(), name.size() * sizeof(QChar)));
|
||||
: base::crc32(name.constData(), name.size() * sizeof(QChar)));
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "api/api_hash.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "main/main_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item_components.h"
|
||||
@ -298,8 +299,7 @@ HistoryItem *ScheduledMessages::append(
|
||||
message.match([&](const MTPDmessage &data) {
|
||||
existing->updateSentContent({
|
||||
qs(data.vmessage()),
|
||||
TextUtilities::EntitiesFromMTP(
|
||||
data.ventities().value_or_empty())
|
||||
Api::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||
}, data.vmedia());
|
||||
existing->updateReplyMarkup(data.vreply_markup());
|
||||
existing->updateForwardedInfo(data.vfwd_from());
|
||||
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
#include "mainwidget.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "core/application.h"
|
||||
#include "core/crash_reports.h" // CrashReports::SetAnnotation
|
||||
#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)) {
|
||||
existing->updateSentContent({
|
||||
qs(data.vmessage()),
|
||||
TextUtilities::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||
Api::EntitiesFromMTP(data.ventities().value_or_empty())
|
||||
}, data.vmedia());
|
||||
existing->updateReplyMarkup(data.vreply_markup());
|
||||
existing->updateForwardedInfo(data.vfwd_from());
|
||||
@ -3676,7 +3677,7 @@ void Session::insertCheckedServiceNotification(
|
||||
MTP_string(sending.text),
|
||||
media,
|
||||
MTPReplyMarkup(),
|
||||
TextUtilities::EntitiesToMTP(sending.entities),
|
||||
Api::EntitiesToMTP(sending.entities),
|
||||
MTPint(),
|
||||
MTPint(),
|
||||
MTPstring(),
|
||||
|
@ -727,7 +727,7 @@ void Widget::onDraggingScrollDelta(int delta) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 Ui {
|
||||
|
@ -74,9 +74,6 @@ void activateBotCommand(
|
||||
void searchByHashtag(const QString &tag, PeerData *inPeer);
|
||||
void showSettings();
|
||||
|
||||
void activateClickHandler(ClickHandlerPtr handler, ClickContext context);
|
||||
void activateClickHandler(ClickHandlerPtr handler, Qt::MouseButton button);
|
||||
|
||||
} // namespace App
|
||||
|
||||
namespace Ui {
|
||||
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/inactive_press.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "lang/lang_keys.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_document.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_user.h"
|
||||
#include "facades.h"
|
||||
@ -515,6 +517,10 @@ QPoint InnerWidget::tooltipPos() const {
|
||||
return _mousePosition;
|
||||
}
|
||||
|
||||
bool InnerWidget::tooltipWindowActive() const {
|
||||
return Ui::InFocusChain(window());
|
||||
}
|
||||
|
||||
HistoryView::Context InnerWidget::elementContext() {
|
||||
return HistoryView::Context::AdminLog;
|
||||
}
|
||||
@ -941,7 +947,7 @@ void InnerWidget::keyPressEvent(QKeyEvent *e) {
|
||||
copySelectedText();
|
||||
#ifdef Q_OS_MAC
|
||||
} 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
|
||||
} else {
|
||||
e->ignore();
|
||||
@ -1143,7 +1149,7 @@ void InnerWidget::copyContextImage(PhotoData *photo) {
|
||||
}
|
||||
|
||||
void InnerWidget::copySelectedText() {
|
||||
SetClipboardText(getSelectedText());
|
||||
TextUtilities::SetClipboardText(getSelectedText());
|
||||
}
|
||||
|
||||
void InnerWidget::showStickerPackInfo(not_null<DocumentData*> document) {
|
||||
@ -1174,7 +1180,7 @@ void InnerWidget::openContextGif(FullMsgId itemId) {
|
||||
|
||||
void InnerWidget::copyContextText(FullMsgId 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(
|
||||
mapFromGlobal(screenPos),
|
||||
_mouseActionItem);
|
||||
_pressWasInactive = _controller->widget()->wasInactivePress();
|
||||
if (_pressWasInactive) _controller->widget()->setInactivePress(false);
|
||||
_pressWasInactive = Ui::WasInactivePress(_controller->widget());
|
||||
if (_pressWasInactive) {
|
||||
Ui::MarkInactivePress(_controller->widget(), false);
|
||||
}
|
||||
|
||||
if (ClickHandler::getPressed()) {
|
||||
_mouseAction = MouseAction::PrepareDrag;
|
||||
@ -1412,7 +1420,7 @@ void InnerWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton but
|
||||
|
||||
if (activated) {
|
||||
mouseActionCancel();
|
||||
App::activateClickHandler(activated, button);
|
||||
ActivateClickHandler(window(), activated, button);
|
||||
return;
|
||||
}
|
||||
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 (_selectedItem && _selectedText.from != _selectedText.to) {
|
||||
SetClipboardText(
|
||||
TextUtilities::SetClipboardText(
|
||||
_selectedItem->selectedText(_selectedText),
|
||||
QClipboard::Selection);
|
||||
}
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
// Ui::AbstractTooltipShower interface.
|
||||
QString tooltipText() const override;
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
// HistoryView::ElementDelegate interface.
|
||||
HistoryView::Context elementContext() override;
|
||||
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history_service.h"
|
||||
#include "history/history_message.h"
|
||||
#include "history/history.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_session.h"
|
||||
@ -116,7 +117,7 @@ TextWithEntities ExtractEditedText(const MTPMessage &message) {
|
||||
const auto &data = message.c_message();
|
||||
return {
|
||||
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;
|
||||
|
||||
historyPhotoLeft: 14px;
|
||||
historyMessageRadius: 6px;
|
||||
historyMessageRadius: roundRadiusLarge;
|
||||
historyBubbleTailInLeft: icon {{ "bubble_tail", msgInBg }};
|
||||
historyBubbleTailInLeftSelected: icon {{ "bubble_tail", msgInBgSelected }};
|
||||
historyBubbleTailOutLeft: icon {{ "bubble_tail", msgOutBg }};
|
||||
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/inactive_press.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_peer_menu.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_photo.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "facades.h"
|
||||
#include "app.h"
|
||||
|
||||
@ -826,23 +828,23 @@ void HistoryInner::touchUpdateSpeed() {
|
||||
|
||||
// fingers are inacurates, we ignore small changes to avoid stopping the autoscroll because
|
||||
// of a small horizontal offset when scrolling vertically
|
||||
const int newSpeedY = (qAbs(pixelsPerSecond.y()) > FingerAccuracyThreshold) ? pixelsPerSecond.y() : 0;
|
||||
const int newSpeedX = (qAbs(pixelsPerSecond.x()) > FingerAccuracyThreshold) ? pixelsPerSecond.x() : 0;
|
||||
const int newSpeedY = (qAbs(pixelsPerSecond.y()) > Ui::kFingerAccuracyThreshold) ? pixelsPerSecond.y() : 0;
|
||||
const int newSpeedX = (qAbs(pixelsPerSecond.x()) > Ui::kFingerAccuracyThreshold) ? pixelsPerSecond.x() : 0;
|
||||
if (_touchScrollState == Ui::TouchScrollState::Auto) {
|
||||
const int oldSpeedY = _touchSpeed.y();
|
||||
const int oldSpeedX = _touchSpeed.x();
|
||||
if ((oldSpeedY <= 0 && newSpeedY <= 0) || ((oldSpeedY >= 0 && newSpeedY >= 0)
|
||||
&& (oldSpeedX <= 0 && newSpeedX <= 0)) || (oldSpeedX >= 0 && newSpeedX >= 0)) {
|
||||
_touchSpeed.setY(snap((oldSpeedY + (newSpeedY / 4)), -MaxScrollAccelerated, +MaxScrollAccelerated));
|
||||
_touchSpeed.setX(snap((oldSpeedX + (newSpeedX / 4)), -MaxScrollAccelerated, +MaxScrollAccelerated));
|
||||
_touchSpeed.setY(snap((oldSpeedY + (newSpeedY / 4)), -Ui::kMaxScrollAccelerated, +Ui::kMaxScrollAccelerated));
|
||||
_touchSpeed.setX(snap((oldSpeedX + (newSpeedX / 4)), -Ui::kMaxScrollAccelerated, +Ui::kMaxScrollAccelerated));
|
||||
} else {
|
||||
_touchSpeed = QPoint();
|
||||
}
|
||||
} else {
|
||||
// we average the speed to avoid strange effects with the last delta
|
||||
if (!_touchSpeed.isNull()) {
|
||||
_touchSpeed.setX(snap((_touchSpeed.x() / 4) + (newSpeedX * 3 / 4), -MaxScrollFlick, +MaxScrollFlick));
|
||||
_touchSpeed.setY(snap((_touchSpeed.y() / 4) + (newSpeedY * 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), -Ui::kMaxScrollFlick, +Ui::kMaxScrollFlick));
|
||||
} else {
|
||||
_touchSpeed = QPoint(newSpeedX, newSpeedY);
|
||||
}
|
||||
@ -1033,8 +1035,10 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
||||
? mouseActionView->data().get()
|
||||
: nullptr;
|
||||
_dragStartPosition = mapPointToItem(mapFromGlobal(screenPos), mouseActionView);
|
||||
_pressWasInactive = _controller->widget()->wasInactivePress();
|
||||
if (_pressWasInactive) _controller->widget()->setInactivePress(false);
|
||||
_pressWasInactive = Ui::WasInactivePress(_controller->widget());
|
||||
if (_pressWasInactive) {
|
||||
Ui::MarkInactivePress(_controller->widget(), false);
|
||||
}
|
||||
|
||||
if (ClickHandler::getPressed()) {
|
||||
_mouseAction = MouseAction::PrepareDrag;
|
||||
@ -1187,7 +1191,7 @@ std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
|
||||
}
|
||||
return TextForMimeData();
|
||||
}();
|
||||
if (auto mimeData = MimeDataFromText(selectedText)) {
|
||||
if (auto mimeData = TextUtilities::MimeDataFromText(selectedText)) {
|
||||
updateDragSelection(nullptr, nullptr, false);
|
||||
_widget->noSelectingScroll();
|
||||
|
||||
@ -1343,7 +1347,7 @@ void HistoryInner::mouseActionFinish(
|
||||
const auto pressedItemId = pressedItemView
|
||||
? pressedItemView->data()->fullId()
|
||||
: FullMsgId();
|
||||
App::activateClickHandler(activated, {
|
||||
ActivateClickHandler(window(), activated, {
|
||||
button,
|
||||
QVariant::fromValue(pressedItemId)
|
||||
});
|
||||
@ -1401,7 +1405,7 @@ void HistoryInner::mouseActionFinish(
|
||||
if (!_selected.empty() && _selected.cbegin()->second != FullSelection) {
|
||||
const auto [item, selection] = *_selected.cbegin();
|
||||
if (const auto view = item->mainView()) {
|
||||
SetClipboardText(
|
||||
TextUtilities::SetClipboardText(
|
||||
view->selectedText(selection),
|
||||
QClipboard::Selection);
|
||||
}
|
||||
@ -1818,7 +1822,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||
}
|
||||
|
||||
void HistoryInner::copySelectedText() {
|
||||
SetClipboardText(getSelectedText());
|
||||
TextUtilities::SetClipboardText(getSelectedText());
|
||||
}
|
||||
|
||||
void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
|
||||
@ -1893,9 +1897,9 @@ void HistoryInner::saveContextGif(FullMsgId itemId) {
|
||||
void HistoryInner::copyContextText(FullMsgId itemId) {
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
if (const auto group = session().data().groups().find(item)) {
|
||||
SetClipboardText(HistoryGroupText(group));
|
||||
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||
} else {
|
||||
SetClipboardText(HistoryItemText(item));
|
||||
TextUtilities::SetClipboardText(HistoryItemText(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1986,7 +1990,7 @@ void HistoryInner::keyPressEvent(QKeyEvent *e) {
|
||||
#ifdef Q_OS_MAC
|
||||
} 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
|
||||
} else if (e == QKeySequence::Delete) {
|
||||
auto selectedState = getSelectionState();
|
||||
@ -3194,6 +3198,10 @@ QPoint HistoryInner::tooltipPos() const {
|
||||
return _mousePosition;
|
||||
}
|
||||
|
||||
bool HistoryInner::tooltipWindowActive() const {
|
||||
return Ui::InFocusChain(window());
|
||||
}
|
||||
|
||||
void HistoryInner::onParentGeometryChanged() {
|
||||
auto mousePos = QCursor::pos();
|
||||
auto mouseOver = _widget->rect().contains(_widget->mapFromGlobal(mousePos));
|
||||
|
@ -110,6 +110,7 @@ public:
|
||||
// Ui::AbstractTooltipShower interface.
|
||||
QString tooltipText() const override;
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
// HistoryView::ElementDelegate interface.
|
||||
static not_null<HistoryView::ElementDelegate*> ElementDelegate();
|
||||
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "mainwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "apiwrap.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history_location_manager.h"
|
||||
@ -442,7 +443,7 @@ HistoryMessage::HistoryMessage(
|
||||
}
|
||||
setText({
|
||||
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()) {
|
||||
setGroupId(
|
||||
@ -1051,7 +1052,7 @@ void HistoryMessage::applyEdition(const MTPDmessage &message) {
|
||||
|
||||
const auto textWithEntities = TextWithEntities{
|
||||
qs(message.vmessage()),
|
||||
TextUtilities::EntitiesFromMTP(message.ventities().value_or_empty())
|
||||
Api::EntitiesFromMTP(message.ventities().value_or_empty())
|
||||
};
|
||||
setReplyMarkup(message.vreply_markup());
|
||||
if (!isLocalUpdateMedia()) {
|
||||
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history_widget.h"
|
||||
|
||||
#include "api/api_sending.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "boxes/send_files_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/text_options.h"
|
||||
#include "ui/unread_badge.h"
|
||||
#include "ui/delayed_activation.h"
|
||||
#include "main/main_session.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/notifications_manager.h"
|
||||
@ -133,7 +135,7 @@ ApiWrap::RequestMessageDataCallback replyEditMessageDataCallback() {
|
||||
void ActivateWindow(not_null<Window::SessionController*> controller) {
|
||||
const auto window = controller->widget();
|
||||
window->activateWindow();
|
||||
Core::App().activateWindowDelayed(window);
|
||||
Ui::ActivateWindowDelayed(window);
|
||||
}
|
||||
|
||||
bool ShowHistoryEndInsteadOfUnread(
|
||||
@ -2833,7 +2835,9 @@ void HistoryWidget::saveEditMsg() {
|
||||
_history,
|
||||
session().user()).flags;
|
||||
auto sending = TextWithEntities();
|
||||
auto left = TextWithEntities { textWithTags.text, ConvertTextTagsToEntities(textWithTags.tags) };
|
||||
auto left = TextWithEntities {
|
||||
textWithTags.text,
|
||||
TextUtilities::ConvertTextTagsToEntities(textWithTags.tags) };
|
||||
TextUtilities::PrepareForSending(left, prepareFlags);
|
||||
|
||||
if (!TextUtilities::CutPart(sending, left, MaxMessageSize)) {
|
||||
@ -2854,8 +2858,10 @@ void HistoryWidget::saveEditMsg() {
|
||||
if (webPageId == CancelledWebPageId) {
|
||||
sendFlags |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
||||
}
|
||||
auto localEntities = TextUtilities::EntitiesToMTP(sending.entities);
|
||||
auto sentEntities = TextUtilities::EntitiesToMTP(sending.entities, TextUtilities::ConvertOption::SkipLocal);
|
||||
auto localEntities = Api::EntitiesToMTP(sending.entities);
|
||||
auto sentEntities = Api::EntitiesToMTP(
|
||||
sending.entities,
|
||||
Api::ConvertOption::SkipLocal);
|
||||
if (!sentEntities.v.isEmpty()) {
|
||||
sendFlags |= MTPmessages_EditMessage::Flag::f_entities;
|
||||
}
|
||||
@ -4497,14 +4503,14 @@ void HistoryWidget::sendFileConfirmed(
|
||||
|
||||
auto caption = TextWithEntities{
|
||||
file->caption.text,
|
||||
ConvertTextTagsToEntities(file->caption.tags)
|
||||
TextUtilities::ConvertTextTagsToEntities(file->caption.tags)
|
||||
};
|
||||
const auto prepareFlags = Ui::ItemTextOptions(
|
||||
history,
|
||||
session().user()).flags;
|
||||
TextUtilities::PrepareForSending(caption, prepareFlags);
|
||||
TextUtilities::Trim(caption);
|
||||
auto localEntities = TextUtilities::EntitiesToMTP(caption.entities);
|
||||
auto localEntities = Api::EntitiesToMTP(caption.entities);
|
||||
|
||||
if (itemToEdit) {
|
||||
if (const auto id = itemToEdit->groupId()) {
|
||||
@ -6870,7 +6876,7 @@ QPoint HistoryWidget::clampMousePosition(QPoint point) {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_groups.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "platform/platform_info.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_items(tr::now);
|
||||
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 (asGroup) {
|
||||
if (const auto group = owner->groups().find(item)) {
|
||||
SetClipboardText(HistoryGroupText(group));
|
||||
TextUtilities::SetClipboardText(HistoryGroupText(group));
|
||||
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 "ui/widgets/popup_menu.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/inactive_press.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "boxes/peers/edit_participant_box.h"
|
||||
#include "data/data_session.h"
|
||||
@ -1090,6 +1091,10 @@ QPoint ListWidget::tooltipPos() const {
|
||||
return _mousePosition;
|
||||
}
|
||||
|
||||
bool ListWidget::tooltipWindowActive() const {
|
||||
return Ui::InFocusChain(window());
|
||||
}
|
||||
|
||||
Context ListWidget::elementContext() {
|
||||
return _delegate->listContext();
|
||||
}
|
||||
@ -1545,11 +1550,11 @@ void ListWidget::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
} else if (e == QKeySequence::Copy
|
||||
&& (hasSelectedText() || hasSelectedItems())) {
|
||||
SetClipboardText(getSelectedText());
|
||||
TextUtilities::SetClipboardText(getSelectedText());
|
||||
#ifdef Q_OS_MAC
|
||||
} 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
|
||||
} else if (e == QKeySequence::Delete) {
|
||||
_delegate->listDeleteRequest();
|
||||
@ -1893,8 +1898,10 @@ void ListWidget::mouseActionStart(
|
||||
const auto pressElement = _overElement;
|
||||
|
||||
_mouseAction = MouseAction::None;
|
||||
_pressWasInactive = _controller->widget()->wasInactivePress();
|
||||
if (_pressWasInactive) _controller->widget()->setInactivePress(false);
|
||||
_pressWasInactive = Ui::WasInactivePress(_controller->widget());
|
||||
if (_pressWasInactive) {
|
||||
Ui::MarkInactivePress(_controller->widget(), false);
|
||||
}
|
||||
|
||||
if (ClickHandler::getPressed()) {
|
||||
_mouseAction = MouseAction::PrepareDrag;
|
||||
@ -2016,7 +2023,7 @@ void ListWidget::mouseActionFinish(
|
||||
activated = nullptr;
|
||||
} else if (activated) {
|
||||
mouseActionCancel();
|
||||
App::activateClickHandler(activated, {
|
||||
ActivateClickHandler(window(), activated, {
|
||||
button,
|
||||
QVariant::fromValue(pressState.itemId)
|
||||
});
|
||||
@ -2058,7 +2065,7 @@ void ListWidget::mouseActionFinish(
|
||||
if (_selectedTextItem
|
||||
&& _selectedTextRange.from != _selectedTextRange.to) {
|
||||
if (const auto view = viewForItem(_selectedTextItem)) {
|
||||
SetClipboardText(
|
||||
TextUtilities::SetClipboardText(
|
||||
view->selectedText(_selectedTextRange),
|
||||
QClipboard::Selection);
|
||||
}
|
||||
@ -2303,7 +2310,7 @@ std::unique_ptr<QMimeData> ListWidget::prepareDrag() {
|
||||
}
|
||||
return TextForMimeData();
|
||||
}();
|
||||
if (auto mimeData = MimeDataFromText(selectedText)) {
|
||||
if (auto mimeData = TextUtilities::MimeDataFromText(selectedText)) {
|
||||
clearDragSelection();
|
||||
// _widget->noSelectingScroll(); #TODO scroll
|
||||
|
||||
|
@ -178,6 +178,7 @@ public:
|
||||
// AbstractTooltipShower interface
|
||||
QString tooltipText() const override;
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
// ElementDelegate interface.
|
||||
Context elementContext() override;
|
||||
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/image/image.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "app.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 "data/data_session.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
#include "styles/style_history.h"
|
||||
|
||||
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/file_download.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "ui/inactive_press.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mainwidget.h"
|
||||
@ -1823,8 +1824,13 @@ void ListWidget::mouseActionStart(
|
||||
auto pressLayout = _overLayout;
|
||||
|
||||
_mouseAction = MouseAction::None;
|
||||
_pressWasInactive = _controller->parentController()->widget()->wasInactivePress();
|
||||
if (_pressWasInactive) _controller->parentController()->widget()->setInactivePress(false);
|
||||
_pressWasInactive = Ui::WasInactivePress(
|
||||
_controller->parentController()->widget());
|
||||
if (_pressWasInactive) {
|
||||
Ui::MarkInactivePress(
|
||||
_controller->parentController()->widget(),
|
||||
false);
|
||||
}
|
||||
|
||||
if (ClickHandler::getPressed() && !hasSelected()) {
|
||||
_mouseAction = MouseAction::PrepareDrag;
|
||||
@ -2018,7 +2024,7 @@ void ListWidget::mouseActionFinish(
|
||||
_wasSelectedText = false;
|
||||
if (activated) {
|
||||
mouseActionCancel();
|
||||
App::activateClickHandler(activated, button);
|
||||
ActivateClickHandler(window(), activated, button);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2045,7 +2051,7 @@ void ListWidget::mouseActionFinish(
|
||||
|
||||
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
|
||||
//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
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
|
||||
#include "api/api_text_entities.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_session.h"
|
||||
@ -136,7 +137,7 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
|
||||
case mtpc_botInlineMessageMediaAuto: {
|
||||
const auto &r = message->c_botInlineMessageMediaAuto();
|
||||
const auto message = qs(r.vmessage());
|
||||
const auto entities = TextUtilities::EntitiesFromMTP(
|
||||
const auto entities = Api::EntitiesFromMTP(
|
||||
r.ventities().value_or_empty());
|
||||
if (result->_type == Type::Photo) {
|
||||
if (!result->_photo) {
|
||||
@ -168,7 +169,7 @@ std::unique_ptr<Result> Result::create(uint64 queryId, const MTPBotInlineResult
|
||||
const auto &r = message->c_botInlineMessageText();
|
||||
result->sendData = std::make_unique<internal::SendText>(
|
||||
qs(r.vmessage()),
|
||||
TextUtilities::EntitiesFromMTP(r.ventities().value_or_empty()),
|
||||
Api::EntitiesFromMTP(r.ventities().value_or_empty()),
|
||||
r.is_no_webpage());
|
||||
if (result->_type == Type::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 "api/api_text_entities.h"
|
||||
#include "data/data_document.h"
|
||||
#include "inline_bots/inline_bot_result.h"
|
||||
#include "storage/localstorage.h"
|
||||
@ -78,7 +79,7 @@ QString SendDataCommon::getErrorOnSend(
|
||||
SendDataCommon::SentMTPMessageFields SendText::getSentMessageFields() const {
|
||||
SentMTPMessageFields result;
|
||||
result.text = MTP_string(_message);
|
||||
result.entities = TextUtilities::EntitiesToMTP(_entities);
|
||||
result.entities = Api::EntitiesToMTP(_entities);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -146,6 +146,10 @@ QPoint Inner::tooltipPos() const {
|
||||
return _lastMousePos;
|
||||
}
|
||||
|
||||
bool Inner::tooltipWindowActive() const {
|
||||
return Ui::InFocusChain(window());
|
||||
}
|
||||
|
||||
Inner::~Inner() = default;
|
||||
|
||||
void Inner::paintEvent(QPaintEvent *e) {
|
||||
@ -239,7 +243,7 @@ void Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
int row = _selected / MatrixRowShift, column = _selected % MatrixRowShift;
|
||||
selectInlineResult(row, column);
|
||||
} 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);
|
||||
auto inner = rect().marginsRemoved(st::emojiPanMargins);
|
||||
_showAnimation->setFinalImage(std::move(image), QRect(inner.topLeft() * cIntRetinaFactor(), inner.size() * cIntRetinaFactor()));
|
||||
auto corners = App::cornersMask(ImageRoundRadius::Small);
|
||||
_showAnimation->setCornerMasks(corners[0], corners[1], corners[2], corners[3]);
|
||||
_showAnimation->setCornerMasks(Images::CornersMask(ImageRoundRadius::Small));
|
||||
_showAnimation->start();
|
||||
}
|
||||
hideChildren();
|
||||
|
@ -86,6 +86,7 @@ public:
|
||||
// Ui::AbstractTooltipShower interface.
|
||||
QString tooltipText() const override;
|
||||
QPoint tooltipPos() const override;
|
||||
bool tooltipWindowActive() const override;
|
||||
|
||||
~Inner();
|
||||
|
||||
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/special_fields.h"
|
||||
#include "main/main_account.h"
|
||||
#include "boxes/confirm_phone_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_user.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "api/api_text_entities.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
@ -3818,7 +3819,7 @@ void MainWidget::feedUpdates(const MTPUpdates &updates, uint64 randomId) {
|
||||
}
|
||||
item->updateSentContent({
|
||||
sent.text,
|
||||
TextUtilities::EntitiesFromMTP(list.value_or_empty())
|
||||
Api::EntitiesFromMTP(list.value_or_empty())
|
||||
}, d.vmedia());
|
||||
item->contributeToSlowmode(d.vdate().v);
|
||||
if (!wasAlready) {
|
||||
@ -4321,7 +4322,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
const auto &d = update.c_updateServiceNotification();
|
||||
const auto text = TextWithEntities {
|
||||
qs(d.vmessage()),
|
||||
TextUtilities::EntitiesFromMTP(d.ventities().v)
|
||||
Api::EntitiesFromMTP(d.ventities().v)
|
||||
};
|
||||
if (IsForceLogoutNotification(d)) {
|
||||
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/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "lang/lang_cloud_manager.h"
|
||||
@ -154,6 +155,11 @@ void MainWindow::firstShow() {
|
||||
|
||||
psFirstShow();
|
||||
updateTrayMenu();
|
||||
|
||||
windowDeactivateEvents(
|
||||
) | rpl::start_with_next([=] {
|
||||
Ui::Tooltip::Hide();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void MainWindow::clearWidgetsHook() {
|
||||
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/platform/ui_platform_utility.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/text_options.h"
|
||||
#include "ui/ui_utility.h"
|
||||
@ -1115,9 +1116,9 @@ void OverlayWidget::onSaveAs() {
|
||||
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);
|
||||
psShowOverAll(this);
|
||||
Ui::Platform::ShowOverAll(this);
|
||||
if (!file.isEmpty() && file != location.name()) {
|
||||
if (_doc->data().isEmpty()) {
|
||||
QFile(file).remove();
|
||||
@ -1141,7 +1142,7 @@ void OverlayWidget::onSaveAs() {
|
||||
} else {
|
||||
if (!_photo || !_photo->loaded()) return;
|
||||
|
||||
psBringToBack(this);
|
||||
Ui::Platform::BringToBack(this);
|
||||
auto filter = qsl("JPEG Image (*.jpg);;") + FileDialog::AllFilesFilter();
|
||||
FileDialog::GetWritePath(
|
||||
this,
|
||||
@ -1153,13 +1154,13 @@ void OverlayWidget::onSaveAs() {
|
||||
QString(),
|
||||
false,
|
||||
_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()) {
|
||||
photo->large()->original().save(result, "JPG");
|
||||
}
|
||||
psShowOverAll(this);
|
||||
}), crl::guard(this, [this] {
|
||||
psShowOverAll(this);
|
||||
Ui::Platform::ShowOverAll(this);
|
||||
}), crl::guard(this, [=] {
|
||||
Ui::Platform::ShowOverAll(this);
|
||||
}));
|
||||
}
|
||||
activateWindow();
|
||||
@ -1977,13 +1978,13 @@ void OverlayWidget::updateThemePreviewGeometry() {
|
||||
void OverlayWidget::displayFinished() {
|
||||
updateControls();
|
||||
if (isHidden()) {
|
||||
psUpdateOverlayed(this);
|
||||
Ui::Platform::UpdateOverlayed(this);
|
||||
#ifdef Q_OS_LINUX
|
||||
showFullScreen();
|
||||
#else // Q_OS_LINUX
|
||||
show();
|
||||
#endif // Q_OS_LINUX
|
||||
psShowOverAll(this);
|
||||
Ui::Platform::ShowOverAll(this);
|
||||
activateWindow();
|
||||
QApplication::setActiveWindow(this);
|
||||
setFocus();
|
||||
@ -3497,7 +3498,7 @@ void OverlayWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
showSaveMsgFile();
|
||||
return;
|
||||
}
|
||||
App::activateClickHandler(activated, e->button());
|
||||
ActivateClickHandler(this, activated, e->button());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
|
||||
#include "ui/special_fields.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "boxes/confirm_phone_box.h"
|
||||
#include "data/data_user.h"
|
||||
|
@ -23,7 +23,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QProcess>
|
||||
#include <QtCore/QVersionNumber>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@ -92,10 +91,6 @@ void FallbackFontConfig() {
|
||||
|
||||
namespace Platform {
|
||||
|
||||
bool IsApplicationActive() {
|
||||
return QApplication::activeWindow() != nullptr;
|
||||
}
|
||||
|
||||
void SetApplicationIcon(const QIcon &icon) {
|
||||
QApplication::setWindowIcon(icon);
|
||||
}
|
||||
@ -135,12 +130,6 @@ QRect psDesktopRect() {
|
||||
return _monitorRect;
|
||||
}
|
||||
|
||||
void psShowOverAll(QWidget *w, bool canFocus) {
|
||||
}
|
||||
|
||||
void psBringToBack(QWidget *w) {
|
||||
}
|
||||
|
||||
void psWriteDump() {
|
||||
}
|
||||
|
||||
@ -243,29 +232,6 @@ void 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() {
|
||||
#ifndef TDESKTOP_DISABLE_REGISTER_CUSTOM_SCHEME
|
||||
auto home = getHomeDir();
|
||||
@ -432,9 +398,6 @@ void psAutoStart(bool start, bool silent) {
|
||||
void psSendToMenu(bool send, bool silent) {
|
||||
}
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget) {
|
||||
}
|
||||
|
||||
bool linuxMoveFile(const char *from, const char *to) {
|
||||
FILE *ffrom = fopen(from, "rb"), *fto = fopen(to, "wb");
|
||||
if (!ffrom) {
|
||||
|
@ -20,26 +20,15 @@ namespace Platform {
|
||||
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[]);
|
||||
|
||||
inline std::optional<crl::time> LastUserInputTime() {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline void IgnoreApplicationActivationRightNow() {
|
||||
}
|
||||
|
||||
inline constexpr bool UseMainQueueGeneric() {
|
||||
return true;
|
||||
}
|
||||
@ -70,15 +59,12 @@ void psAutoStart(bool start, bool silent = false);
|
||||
void psSendToMenu(bool send, bool silent = false);
|
||||
|
||||
QRect psDesktopRect();
|
||||
void psShowOverAll(QWidget *w, bool canFocus = true);
|
||||
void psBringToBack(QWidget *w);
|
||||
|
||||
int psCleanup();
|
||||
int psFixPrevious();
|
||||
|
||||
void psNewVersion();
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget);
|
||||
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_session.h"
|
||||
#include "dialogs/dialogs_layout.h"
|
||||
#include "emoji_config.h"
|
||||
#include "ui/emoji_config.h"
|
||||
#include "history/history.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "mainwidget.h"
|
||||
|
@ -16,10 +16,6 @@ class LocationPoint;
|
||||
|
||||
namespace Platform {
|
||||
|
||||
inline bool TranslucentWindowsSupported(QPoint globalPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CurrentExecutablePath(int argc, char *argv[]);
|
||||
|
||||
void RemoveQuarantine(const QString &path);
|
||||
@ -67,8 +63,6 @@ void psAutoStart(bool start, bool silent = false);
|
||||
void psSendToMenu(bool send, bool silent = false);
|
||||
|
||||
QRect psDesktopRect();
|
||||
void psShowOverAll(QWidget *w, bool canFocus = true);
|
||||
void psBringToBack(QWidget *w);
|
||||
|
||||
int psCleanup();
|
||||
int psFixPrevious();
|
||||
@ -77,8 +71,6 @@ bool psShowOpenWithMenu(int x, int y, const QString &file);
|
||||
|
||||
void psNewVersion();
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget);
|
||||
|
||||
void psDownloadPathEnableAccess();
|
||||
QByteArray psDownloadPathBookmark(const QString &path);
|
||||
QByteArray psPathBookmark(const QString &path);
|
||||
|
@ -60,14 +60,6 @@ QRect psDesktopRect() {
|
||||
return _monitorRect;
|
||||
}
|
||||
|
||||
void psShowOverAll(QWidget *w, bool canFocus) {
|
||||
objc_showOverAll(w->winId(), canFocus);
|
||||
}
|
||||
|
||||
void psBringToBack(QWidget *w) {
|
||||
objc_bringToBack(w->winId());
|
||||
}
|
||||
|
||||
void psWriteDump() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
double v = objc_appkitVersion();
|
||||
@ -128,14 +120,6 @@ void 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[]) {
|
||||
return NS2QString([[NSBundle mainBundle] bundlePath]);
|
||||
}
|
||||
@ -274,6 +258,10 @@ std::optional<crl::time> LastUserInputTime() {
|
||||
return (crl::now() - static_cast<crl::time>(idleTime));
|
||||
}
|
||||
|
||||
void IgnoreApplicationActivationRightNow() {
|
||||
objc_ignoreApplicationActivationRightNow();
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
||||
void psNewVersion() {
|
||||
@ -286,9 +274,6 @@ void psAutoStart(bool start, bool silent) {
|
||||
void psSendToMenu(bool send, bool silent) {
|
||||
}
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget) {
|
||||
}
|
||||
|
||||
void psDownloadPathEnableAccess() {
|
||||
objc_downloadPathEnableAccess(Global::DownloadPathBookmark());
|
||||
}
|
||||
|
@ -11,8 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
bool objc_handleMediaKeyEvent(void *e);
|
||||
|
||||
bool objc_darkMode();
|
||||
void objc_showOverAll(WId winId, bool canFocus = true);
|
||||
void objc_bringToBack(WId winId);
|
||||
|
||||
void objc_debugShowAlert(const QString &str);
|
||||
void objc_outputDebugString(const QString &str);
|
||||
|
@ -35,8 +35,6 @@ namespace {
|
||||
|
||||
constexpr auto kIgnoreActivationTimeoutMs = 500;
|
||||
|
||||
std::optional<bool> ApplicationIsActive;
|
||||
|
||||
} // namespace
|
||||
|
||||
NSImage *qt_mac_create_nsimage(const QPixmap &pm);
|
||||
@ -141,7 +139,6 @@ ApplicationDelegate *_sharedDelegate = nil;
|
||||
}
|
||||
|
||||
- (void) applicationDidBecomeActive:(NSNotification *)aNotification {
|
||||
ApplicationIsActive = true;
|
||||
if (Core::IsAppLaunched() && !_ignoreActivation) {
|
||||
Core::App().handleAppActivated();
|
||||
if (auto window = App::wnd()) {
|
||||
@ -153,7 +150,6 @@ ApplicationDelegate *_sharedDelegate = nil;
|
||||
}
|
||||
|
||||
- (void) applicationDidResignActive:(NSNotification *)aNotification {
|
||||
ApplicationIsActive = false;
|
||||
}
|
||||
|
||||
- (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) {
|
||||
NSImage *image = nil;
|
||||
if (!icon.isNull()) {
|
||||
@ -224,46 +214,6 @@ void SetApplicationIcon(const QIcon &icon) {
|
||||
[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
|
||||
|
||||
bool objc_darkMode() {
|
||||
@ -279,20 +229,6 @@ bool objc_darkMode() {
|
||||
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) {
|
||||
auto e = reinterpret_cast<NSEvent*>(ev);
|
||||
|
||||
|
@ -27,13 +27,7 @@ enum class SystemSettingsType {
|
||||
};
|
||||
|
||||
void SetWatchingMediaKeys(bool watching);
|
||||
bool IsApplicationActive();
|
||||
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();
|
||||
PermissionStatus GetPermissionStatus(PermissionType type);
|
||||
void RequestPermission(PermissionType type, Fn<void(PermissionStatus)> resultCallback);
|
||||
@ -45,6 +39,8 @@ bool OpenSystemSettings(SystemSettingsType type);
|
||||
return LastUserInputTime().has_value();
|
||||
}
|
||||
|
||||
void IgnoreApplicationActivationRightNow();
|
||||
|
||||
[[nodiscard]] constexpr bool UseMainQueueGeneric();
|
||||
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 "window/notifications_manager.h"
|
||||
#include "mainwindow.h"
|
||||
#include "base/crc32hash.h"
|
||||
#include "core/application.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "storage/localstorage.h"
|
||||
@ -661,7 +662,7 @@ int32 MainWindow::screenNameChecksum(const QString &name) const {
|
||||
} else {
|
||||
memcpy(buffer, name.toStdWString().data(), sizeof(buffer));
|
||||
}
|
||||
return hashCrc32(buffer, sizeof(buffer));
|
||||
return base::crc32(buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
void MainWindow::psRefreshTaskbarIcon() {
|
||||
|
@ -201,12 +201,6 @@ QRect psDesktopRect() {
|
||||
return _monitorRect;
|
||||
}
|
||||
|
||||
void psShowOverAll(QWidget *w, bool canFocus) {
|
||||
}
|
||||
|
||||
void psBringToBack(QWidget *w) {
|
||||
}
|
||||
|
||||
int psCleanup() {
|
||||
__try
|
||||
{
|
||||
@ -308,10 +302,6 @@ void start() {
|
||||
void finish() {
|
||||
}
|
||||
|
||||
bool IsApplicationActive() {
|
||||
return QApplication::activeWindow() != nullptr;
|
||||
}
|
||||
|
||||
void SetApplicationIcon(const QIcon &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.");
|
||||
}
|
||||
|
||||
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() {
|
||||
#ifndef TDESKTOP_DISABLE_CRASH_REPORTS
|
||||
PROCESS_MEMORY_COUNTERS data = { 0 };
|
||||
|
@ -19,26 +19,11 @@ namespace Platform {
|
||||
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[]);
|
||||
|
||||
inline void IgnoreApplicationActivationRightNow() {
|
||||
}
|
||||
|
||||
inline constexpr bool UseMainQueueGeneric() {
|
||||
return true;
|
||||
}
|
||||
@ -74,15 +59,12 @@ void psAutoStart(bool start, bool silent = false);
|
||||
void psSendToMenu(bool send, bool silent = false);
|
||||
|
||||
QRect psDesktopRect();
|
||||
void psShowOverAll(QWidget *w, bool canFocus = true);
|
||||
void psBringToBack(QWidget *w);
|
||||
|
||||
int psCleanup();
|
||||
int psFixPrevious();
|
||||
|
||||
void psNewVersion();
|
||||
|
||||
void psUpdateOverlayed(QWidget *widget);
|
||||
inline QByteArray psDownloadPathBookmark(const QString &path) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "platform/win/windows_dlls.h"
|
||||
#include "core/sandbox.h"
|
||||
#include "ui/inactive_press.h"
|
||||
#include "mainwindow.h"
|
||||
#include "main/main_session.h"
|
||||
#include "facades.h"
|
||||
@ -113,7 +114,7 @@ bool EventFilter::mainWindowEvent(
|
||||
|
||||
case WM_ACTIVATE: {
|
||||
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
||||
_window->setInactivePress(true);
|
||||
Ui::MarkInactivePress(_window, true);
|
||||
}
|
||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||
_window->shadowsActivate();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user