mirror of https://github.com/procxx/kepka.git
merged for 0.9.16
This commit is contained in:
commit
433243fcca
|
@ -61,7 +61,7 @@ In Terminal go to **/home/user/TBuild/Libraries** and run
|
||||||
sudo apt-get -y --force-yes install autoconf automake build-essential libass-dev libfreetype6-dev libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev
|
sudo apt-get -y --force-yes install autoconf automake build-essential libass-dev libfreetype6-dev libgpac-dev libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev
|
||||||
sudo apt-get install yasm
|
sudo apt-get install yasm
|
||||||
|
|
||||||
./configure --prefix=/usr/local --disable-programs --disable-pthreads --disable-doc --disable-everything --enable-libopus --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=aasc --enable-decoder=flac --enable-decoder=gif --enable-decoder=h264 --enable-decoder=h264_vdpau --enable-decoder=mp1 --enable-decoder=mp1float --enable-decoder=mp2 --enable-decoder=mp2float --enable-decoder=mp3 --enable-decoder=mp3adu --enable-decoder=mp3adufloat --enable-decoder=mp3float --enable-decoder=mp3on4 --enable-decoder=mp3on4float --enable-decoder=mpeg4 --enable-decoder=mpeg4_vdpau --enable-decoder=msmpeg4v2 --enable-decoder=msmpeg4v3 --enable-decoder=opus --enable-decoder=vorbis --enable-decoder=wavpack --enable-decoder=wmalossless --enable-decoder=wmapro --enable-decoder=wmav1 --enable-decoder=wmav2 --enable-decoder=wmavoice --enable-encoder=libopus --enable-hwaccel=h264_vaapi --enable-hwaccel=h264_vdpau --enable-hwaccel=mpeg4_vaapi --enable-hwaccel=mpeg4_vdpau --enable-parser=aac --enable-parser=aac_latm --enable-parser=flac --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=opus --enable-parser=vorbis --enable-demuxer=aac --enable-demuxer=flac --enable-demuxer=gif --enable-demuxer=h264 --enable-demuxer=mov --enable-demuxer=mp3 --enable-demuxer=ogg --enable-demuxer=wav --enable-muxer=ogg --enable-muxer=opus
|
./configure --prefix=/usr/local --disable-programs --disable-doc --disable-pthreads --disable-mmx --disable-everything --enable-libopus --enable-decoder=aac --enable-decoder=aac_latm --enable-decoder=aasc --enable-decoder=flac --enable-decoder=gif --enable-decoder=h264 --enable-decoder=h264_vdpau --enable-decoder=mp1 --enable-decoder=mp1float --enable-decoder=mp2 --enable-decoder=mp2float --enable-decoder=mp3 --enable-decoder=mp3adu --enable-decoder=mp3adufloat --enable-decoder=mp3float --enable-decoder=mp3on4 --enable-decoder=mp3on4float --enable-decoder=mpeg4 --enable-decoder=mpeg4_vdpau --enable-decoder=msmpeg4v2 --enable-decoder=msmpeg4v3 --enable-decoder=opus --enable-decoder=vorbis --enable-decoder=wavpack --enable-decoder=wmalossless --enable-decoder=wmapro --enable-decoder=wmav1 --enable-decoder=wmav2 --enable-decoder=wmavoice --enable-encoder=libopus --enable-hwaccel=h264_vaapi --enable-hwaccel=h264_vdpau --enable-hwaccel=mpeg4_vaapi --enable-hwaccel=mpeg4_vdpau --enable-parser=aac --enable-parser=aac_latm --enable-parser=flac --enable-parser=h264 --enable-parser=mpeg4video --enable-parser=mpegaudio --enable-parser=opus --enable-parser=vorbis --enable-demuxer=aac --enable-demuxer=flac --enable-demuxer=gif --enable-demuxer=h264 --enable-demuxer=mov --enable-demuxer=mp3 --enable-demuxer=ogg --enable-demuxer=wav --enable-muxer=ogg --enable-muxer=opus
|
||||||
|
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
|
|
@ -1197,6 +1197,18 @@ msgFileRedColor: #e47272;
|
||||||
msgFileYellowColor: #efc274;
|
msgFileYellowColor: #efc274;
|
||||||
msgFileGreenColor: #61b96e;
|
msgFileGreenColor: #61b96e;
|
||||||
msgFileBlueColor: #72b1df;
|
msgFileBlueColor: #72b1df;
|
||||||
|
msgFileRedDark: #cd5b5e;
|
||||||
|
msgFileYellowDark: #e6a561;
|
||||||
|
msgFileGreenDark: #4da859;
|
||||||
|
msgFileBlueDark: #5c9ece;
|
||||||
|
msgFileRedOver: #c35154;
|
||||||
|
msgFileYellowOver: #dc9c5a;
|
||||||
|
msgFileGreenOver: #44a050;
|
||||||
|
msgFileBlueOver: #5294c4;
|
||||||
|
msgFileRedSelected: #9f6a82;
|
||||||
|
msgFileYellowSelected: #b19d84;
|
||||||
|
msgFileGreenSelected: #46a07e;
|
||||||
|
msgFileBlueSelected: #5099d0;
|
||||||
|
|
||||||
msgFileMenuSize: size(36px, 36px);
|
msgFileMenuSize: size(36px, 36px);
|
||||||
msgFileSize: 44px;
|
msgFileSize: 44px;
|
||||||
|
@ -2161,6 +2173,14 @@ overviewPhotoCheck: sprite(245px, 308px, 32px, 32px);
|
||||||
overviewPhotoChecked: sprite(278px, 308px, 32px, 32px);
|
overviewPhotoChecked: sprite(278px, 308px, 32px, 32px);
|
||||||
overviewPhotoSelectOverlay: #0a7bb03f;
|
overviewPhotoSelectOverlay: #0a7bb03f;
|
||||||
|
|
||||||
|
overviewFilePadding: margins(0px, 3px, 16px, 3px);
|
||||||
|
overviewFileSize: 70px;
|
||||||
|
overviewFileNameTop: 7px;
|
||||||
|
overviewFileStatusTop: 27px;
|
||||||
|
overviewFileDateTop: 49px;
|
||||||
|
overviewFileChecked: #2fa9e2;
|
||||||
|
overviewFileCheck: #00000066;
|
||||||
|
|
||||||
// Mac specific
|
// Mac specific
|
||||||
|
|
||||||
macAccessory: size(450, 90);
|
macAccessory: size(450, 90);
|
||||||
|
@ -2346,11 +2366,12 @@ playlistPadding: 10px;
|
||||||
linksSearchMargin: margins(20px, 20px, 20px, 0px);
|
linksSearchMargin: margins(20px, 20px, 20px, 0px);
|
||||||
linksMaxWidth: 520px;
|
linksMaxWidth: 520px;
|
||||||
linksLetterFont: font(24px);
|
linksLetterFont: font(24px);
|
||||||
linksMargin: 5px;
|
linksMargin: margins(0px, 7px, 0px, 5px);
|
||||||
|
linksTextTop: 6px;
|
||||||
linksBorder: 1px;
|
linksBorder: 1px;
|
||||||
linksBorderFg: #eaeaea;
|
linksBorderFg: #eaeaea;
|
||||||
linksDateColor: #000;
|
linksDateColor: #808080;
|
||||||
linksDateMargin: 15px;
|
linksDateMargin: margins(0px, 15px, 0px, 2px);
|
||||||
|
|
||||||
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
linksPhotoCheck: sprite(184px, 196px, 16px, 16px);
|
||||||
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
linksPhotoChecked: sprite(168px, 196px, 16px, 16px);
|
||||||
|
|
|
@ -708,7 +708,7 @@ void Application::checkMapVersion() {
|
||||||
if (cDevVersion() && Local::oldMapVersion() < 9016) {
|
if (cDevVersion() && Local::oldMapVersion() < 9016) {
|
||||||
// versionFeatures = QString::fromUtf8("\xe2\x80\x94 Sticker management: manually rearrange your sticker packs, pack order is now synced across all your devices\n\xe2\x80\x94 Click and hold on a sticker to preview it before sending\n\xe2\x80\x94 New context menu for chats in chats list\n\xe2\x80\x94 Support for all existing emoji");// .replace('@', qsl("@") + QChar(0x200D));
|
// versionFeatures = QString::fromUtf8("\xe2\x80\x94 Sticker management: manually rearrange your sticker packs, pack order is now synced across all your devices\n\xe2\x80\x94 Click and hold on a sticker to preview it before sending\n\xe2\x80\x94 New context menu for chats in chats list\n\xe2\x80\x94 Support for all existing emoji");// .replace('@', qsl("@") + QChar(0x200D));
|
||||||
versionFeatures = lng_new_version_text(lt_gifs_link, qsl("https://telegram.org/blog/gif-revolution"), lt_bots_link, qsl("https://telegram.org/blog/inline-bots")).trimmed();
|
versionFeatures = lng_new_version_text(lt_gifs_link, qsl("https://telegram.org/blog/gif-revolution"), lt_bots_link, qsl("https://telegram.org/blog/inline-bots")).trimmed();
|
||||||
} else if (Local::oldMapVersion() < 9015) {
|
} else if (Local::oldMapVersion() < 9016) {
|
||||||
versionFeatures = lng_new_version_text(lt_gifs_link, qsl("https://telegram.org/blog/gif-revolution"), lt_bots_link, qsl("https://telegram.org/blog/inline-bots")).trimmed();
|
versionFeatures = lng_new_version_text(lt_gifs_link, qsl("https://telegram.org/blog/gif-revolution"), lt_bots_link, qsl("https://telegram.org/blog/inline-bots")).trimmed();
|
||||||
} else {
|
} else {
|
||||||
versionFeatures = lang(lng_new_version_minor).trimmed();
|
versionFeatures = lang(lng_new_version_minor).trimmed();
|
||||||
|
|
|
@ -20,10 +20,10 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
static const int32 AppVersion = 9015;
|
static const int32 AppVersion = 9016;
|
||||||
static const wchar_t *AppVersionStr = L"0.9.15";
|
static const wchar_t *AppVersionStr = L"0.9.16";
|
||||||
static const bool DevVersion = false;
|
static const bool DevVersion = false;
|
||||||
#define BETA_VERSION (9015007ULL) // just comment this line to build public version
|
//#define BETA_VERSION (9015008ULL) // just comment this line to build public version
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
|
|
@ -1663,14 +1663,14 @@ void StickerPanInner::refreshStickers() {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth) {
|
bool StickerPanInner::inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth) {
|
||||||
LayoutInlineItem *layout = 0;
|
LayoutInlineItem *layout = 0;
|
||||||
if (savedGif) {
|
if (savedGif) {
|
||||||
layout = layoutPrepareSavedGif(savedGif, (_inlineRows.size() * MatrixRowShift) + row.items.size());
|
layout = layoutPrepareSavedGif(savedGif, (_inlineRows.size() * MatrixRowShift) + row.items.size());
|
||||||
} else if (result) {
|
} else if (result) {
|
||||||
layout = layoutPrepareInlineResult(result, (_inlineRows.size() * MatrixRowShift) + row.items.size());
|
layout = layoutPrepareInlineResult(result, (_inlineRows.size() * MatrixRowShift) + row.items.size());
|
||||||
}
|
}
|
||||||
if (!layout) return;
|
if (!layout) return false;
|
||||||
|
|
||||||
layout->preload();
|
layout->preload();
|
||||||
if (inlineRowFinalize(row, sumWidth, layout->fullLine())) {
|
if (inlineRowFinalize(row, sumWidth, layout->fullLine())) {
|
||||||
|
@ -1678,6 +1678,7 @@ void StickerPanInner::inlineRowsAddItem(DocumentData *savedGif, InlineResult *re
|
||||||
}
|
}
|
||||||
row.items.push_back(layout);
|
row.items.push_back(layout);
|
||||||
sumWidth += layout->maxWidth();
|
sumWidth += layout->maxWidth();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickerPanInner::inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force) {
|
bool StickerPanInner::inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force) {
|
||||||
|
@ -1770,7 +1771,7 @@ LayoutInlineItem *StickerPanInner::layoutPrepareInlineResult(InlineResult *resul
|
||||||
layout = new LayoutInlineGif(result, 0, false);
|
layout = new LayoutInlineGif(result, 0, false);
|
||||||
} else if (result->type == qstr("photo")) {
|
} else if (result->type == qstr("photo")) {
|
||||||
layout = new LayoutInlinePhoto(result, 0);
|
layout = new LayoutInlinePhoto(result, 0);
|
||||||
} else if (result->type == qstr("web_player_video")) {
|
} else if (result->type == qstr("video")) {
|
||||||
layout = new LayoutInlineWebVideo(result);
|
layout = new LayoutInlineWebVideo(result);
|
||||||
} else if (result->type == qstr("article")) {
|
} else if (result->type == qstr("article")) {
|
||||||
layout = new LayoutInlineArticle(result, _inlineWithThumb);
|
layout = new LayoutInlineArticle(result, _inlineWithThumb);
|
||||||
|
@ -1901,14 +1902,14 @@ void StickerPanInner::clearInlineRowsPanel() {
|
||||||
clearInlineRows(false);
|
clearInlineRows(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &results, bool resultsDeleted) {
|
int32 StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &results, bool resultsDeleted) {
|
||||||
_inlineBot = bot;
|
_inlineBot = bot;
|
||||||
if (results.isEmpty() && (!_inlineBot || _inlineBot->username != cInlineGifBotUsername())) {
|
if (results.isEmpty() && (!_inlineBot || _inlineBot->username != cInlineGifBotUsername())) {
|
||||||
if (resultsDeleted) {
|
if (resultsDeleted) {
|
||||||
clearInlineRows(true);
|
clearInlineRows(true);
|
||||||
}
|
}
|
||||||
emit emptyInlineRows();
|
emit emptyInlineRows();
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_showingInlineItems) {
|
if (_showingInlineItems) {
|
||||||
|
@ -1921,7 +1922,7 @@ void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &resu
|
||||||
_showingInlineItems = true;
|
_showingInlineItems = true;
|
||||||
_showingSavedGifs = false;
|
_showingSavedGifs = false;
|
||||||
|
|
||||||
int32 count = results.size(), from = validateExistingInlineRows(results);
|
int32 count = results.size(), from = validateExistingInlineRows(results), added = 0;
|
||||||
|
|
||||||
if (count) {
|
if (count) {
|
||||||
_inlineRows.reserve(count);
|
_inlineRows.reserve(count);
|
||||||
|
@ -1929,7 +1930,9 @@ void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &resu
|
||||||
row.items.reserve(SavedGifsMaxPerRow);
|
row.items.reserve(SavedGifsMaxPerRow);
|
||||||
int32 sumWidth = 0;
|
int32 sumWidth = 0;
|
||||||
for (int32 i = from; i < count; ++i) {
|
for (int32 i = from; i < count; ++i) {
|
||||||
inlineRowsAddItem(0, results.at(i), row, sumWidth);
|
if (inlineRowsAddItem(0, results.at(i), row, sumWidth)) {
|
||||||
|
++added;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inlineRowFinalize(row, sumWidth, true);
|
inlineRowFinalize(row, sumWidth, true);
|
||||||
}
|
}
|
||||||
|
@ -1943,6 +1946,8 @@ void StickerPanInner::refreshInlineRows(UserData *bot, const InlineResults &resu
|
||||||
_lastMousePos = QCursor::pos();
|
_lastMousePos = QCursor::pos();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 StickerPanInner::validateExistingInlineRows(const InlineResults &results) {
|
int32 StickerPanInner::validateExistingInlineRows(const InlineResults &results) {
|
||||||
|
@ -3722,7 +3727,10 @@ void EmojiPan::inlineResultsDone(const MTPmessages_BotResults &result) {
|
||||||
} else if (adding) {
|
} else if (adding) {
|
||||||
it.value()->nextOffset = QString();
|
it.value()->nextOffset = QString();
|
||||||
}
|
}
|
||||||
showInlineRows(!adding);
|
|
||||||
|
if (!showInlineRows(!adding)) {
|
||||||
|
it.value()->nextOffset = QString();
|
||||||
|
}
|
||||||
onScroll();
|
onScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3782,7 +3790,7 @@ void EmojiPan::onEmptyInlineRows() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmojiPan::refreshInlineRows() {
|
bool EmojiPan::refreshInlineRows(int32 *added) {
|
||||||
bool clear = true;
|
bool clear = true;
|
||||||
InlineCache::const_iterator i = _inlineCache.constFind(_inlineQuery);
|
InlineCache::const_iterator i = _inlineCache.constFind(_inlineQuery);
|
||||||
if (i != _inlineCache.cend()) {
|
if (i != _inlineCache.cend()) {
|
||||||
|
@ -3790,12 +3798,14 @@ bool EmojiPan::refreshInlineRows() {
|
||||||
_inlineNextOffset = i.value()->nextOffset;
|
_inlineNextOffset = i.value()->nextOffset;
|
||||||
}
|
}
|
||||||
if (clear) prepareShowHideCache();
|
if (clear) prepareShowHideCache();
|
||||||
s_inner.refreshInlineRows(_inlineBot, clear ? InlineResults() : i.value()->results, false);
|
int32 result = s_inner.refreshInlineRows(_inlineBot, clear ? InlineResults() : i.value()->results, false);
|
||||||
|
if (added) *added = result;
|
||||||
return !clear;
|
return !clear;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::showInlineRows(bool newResults) {
|
int32 EmojiPan::showInlineRows(bool newResults) {
|
||||||
bool clear = !refreshInlineRows();
|
int32 added = 0;
|
||||||
|
bool clear = !refreshInlineRows(&added);
|
||||||
if (newResults) s_scroll.scrollToY(0);
|
if (newResults) s_scroll.scrollToY(0);
|
||||||
|
|
||||||
e_switch.updateText(clear ? QString() : _inlineBot->username);
|
e_switch.updateText(clear ? QString() : _inlineBot->username);
|
||||||
|
@ -3819,6 +3829,8 @@ void EmojiPan::showInlineRows(bool newResults) {
|
||||||
onSwitch();
|
onSwitch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::recountContentMaxHeight() {
|
void EmojiPan::recountContentMaxHeight() {
|
||||||
|
|
|
@ -344,7 +344,7 @@ public:
|
||||||
void refreshStickers();
|
void refreshStickers();
|
||||||
void refreshRecentStickers(bool resize = true);
|
void refreshRecentStickers(bool resize = true);
|
||||||
void refreshSavedGifs();
|
void refreshSavedGifs();
|
||||||
void refreshInlineRows(UserData *bot, const InlineResults &results, bool resultsDeleted);
|
int32 refreshInlineRows(UserData *bot, const InlineResults &results, bool resultsDeleted);
|
||||||
void refreshRecent();
|
void refreshRecent();
|
||||||
void inlineBotChanged();
|
void inlineBotChanged();
|
||||||
void hideInlineRowsPanel();
|
void hideInlineRowsPanel();
|
||||||
|
@ -458,7 +458,7 @@ private:
|
||||||
InlineLayouts _inlineLayouts;
|
InlineLayouts _inlineLayouts;
|
||||||
LayoutInlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
|
LayoutInlineItem *layoutPrepareInlineResult(InlineResult *result, int32 position);
|
||||||
|
|
||||||
void inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
|
bool inlineRowsAddItem(DocumentData *savedGif, InlineResult *result, InlineRow &row, int32 &sumWidth);
|
||||||
bool inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
|
bool inlineRowFinalize(InlineRow &row, int32 &sumWidth, bool force = false);
|
||||||
|
|
||||||
InlineRow &layoutInlineRow(InlineRow &row, int32 sumWidth = 0);
|
InlineRow &layoutInlineRow(InlineRow &row, int32 sumWidth = 0);
|
||||||
|
@ -712,10 +712,10 @@ private:
|
||||||
QTimer _inlineRequestTimer;
|
QTimer _inlineRequestTimer;
|
||||||
|
|
||||||
void inlineBotChanged();
|
void inlineBotChanged();
|
||||||
void showInlineRows(bool newResults);
|
int32 showInlineRows(bool newResults);
|
||||||
bool hideOnNoInlineResults();
|
bool hideOnNoInlineResults();
|
||||||
void recountContentMaxHeight();
|
void recountContentMaxHeight();
|
||||||
bool refreshInlineRows();
|
bool refreshInlineRows(int32 *added = 0);
|
||||||
UserData *_inlineBot;
|
UserData *_inlineBot;
|
||||||
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
|
QString _inlineQuery, _inlineNextQuery, _inlineNextOffset;
|
||||||
mtpRequestId _inlineRequestId;
|
mtpRequestId _inlineRequestId;
|
||||||
|
|
|
@ -225,7 +225,7 @@ ClipReader::ClipReader(const FileLocation &location, const QByteArray &data, Cal
|
||||||
, _state(ClipReading)
|
, _state(ClipReading)
|
||||||
, _width(0)
|
, _width(0)
|
||||||
, _height(0)
|
, _height(0)
|
||||||
, _step(FirstFrameNotReadStep)
|
, _step(WaitingForDimensionsStep)
|
||||||
, _paused(0)
|
, _paused(0)
|
||||||
, _autoplay(false)
|
, _autoplay(false)
|
||||||
, _private(0) {
|
, _private(0) {
|
||||||
|
@ -248,47 +248,69 @@ ClipReader::ClipReader(const FileLocation &location, const QByteArray &data, Cal
|
||||||
_clipManagers.at(_threadIndex)->append(this, location, data);
|
_clipManagers.at(_threadIndex)->append(this, location, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipReader::Frame *ClipReader::frameToShow() const { // 0 means not ready
|
ClipReader::Frame *ClipReader::frameToShow(int32 *index) const { // 0 means not ready
|
||||||
int32 step = _step.loadAcquire();
|
int32 step = _step.loadAcquire(), i;
|
||||||
if (step == FirstFrameNotReadStep) {
|
if (step == WaitingForDimensionsStep) {
|
||||||
return 0;
|
|
||||||
} else if (step == WaitingForRequestStep) {
|
|
||||||
return _frames;
|
|
||||||
}
|
|
||||||
return _frames + (((step + 1) / 2) % 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipReader::Frame *ClipReader::frameToWrite(int32 *index) const { // 0 means not ready
|
|
||||||
int32 step = _step.loadAcquire(), i = 0;
|
|
||||||
if (step == WaitingForRequestStep) {
|
|
||||||
if (index) *index = 0;
|
if (index) *index = 0;
|
||||||
return 0;
|
return 0;
|
||||||
} else if (step != FirstFrameNotReadStep) {
|
} else if (step == WaitingForRequestStep) {
|
||||||
i = (((step + 3) / 2) % 3);
|
i = 0;
|
||||||
|
} else if (step == WaitingForFirstFrameStep) {
|
||||||
|
i = 0;
|
||||||
|
} else {
|
||||||
|
i = (step / 2) % 3;
|
||||||
}
|
}
|
||||||
if (index) *index = i;
|
if (index) *index = i;
|
||||||
return _frames + i;
|
return _frames + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipReader::Frame *ClipReader::frameToWriteNext(bool checkNotWriting) const {
|
ClipReader::Frame *ClipReader::frameToWrite(int32 *index) const { // 0 means not ready
|
||||||
int32 step = _step.loadAcquire();
|
int32 step = _step.loadAcquire(), i;
|
||||||
if (step == FirstFrameNotReadStep || step == WaitingForRequestStep || (checkNotWriting && !(step % 2))) {
|
if (step == WaitingForDimensionsStep) {
|
||||||
|
i = 0;
|
||||||
|
} else if (step == WaitingForRequestStep) {
|
||||||
|
if (index) *index = 0;
|
||||||
|
return 0;
|
||||||
|
} else if (step == WaitingForFirstFrameStep) {
|
||||||
|
i = 0;
|
||||||
|
} else {
|
||||||
|
i = ((step + 2) / 2) % 3;
|
||||||
|
}
|
||||||
|
if (index) *index = i;
|
||||||
|
return _frames + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
ClipReader::Frame *ClipReader::frameToWriteNext(bool checkNotWriting, int32 *index) const {
|
||||||
|
int32 step = _step.loadAcquire(), i;
|
||||||
|
if (step == WaitingForDimensionsStep || step == WaitingForRequestStep || (checkNotWriting && (step % 2))) {
|
||||||
|
if (index) *index = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return _frames + (((step + 5) / 2) % 3);
|
i = ((step + 4) / 2) % 3;
|
||||||
|
if (index) *index = i;
|
||||||
|
return _frames + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipReader::moveToNextShow() const {
|
void ClipReader::moveToNextShow() const {
|
||||||
int32 step = _step.loadAcquire();
|
int32 step = _step.loadAcquire();
|
||||||
if (step % 2) {
|
if (step == WaitingForDimensionsStep) {
|
||||||
_step.storeRelease((step + 1) % 6);
|
} else if (step == WaitingForRequestStep) {
|
||||||
|
_step.storeRelease(WaitingForFirstFrameStep);
|
||||||
|
} else if (step == WaitingForFirstFrameStep) {
|
||||||
|
} else if (!(step % 2)) {
|
||||||
|
_step.storeRelease(step + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClipReader::moveToNextWrite() const {
|
void ClipReader::moveToNextWrite() const {
|
||||||
int32 step = _step.loadAcquire();
|
int32 step = _step.loadAcquire();
|
||||||
if (!(step % 2)) {
|
if (step == WaitingForDimensionsStep) {
|
||||||
_step.storeRelease(step + 1);
|
_step.storeRelease(WaitingForRequestStep);
|
||||||
|
} else if (step == WaitingForRequestStep) {
|
||||||
|
} else if (step == WaitingForFirstFrameStep) {
|
||||||
|
_step.storeRelease(0);
|
||||||
|
} else if (step % 2) {
|
||||||
|
_step.storeRelease((step + 1) % 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +335,7 @@ void ClipReader::start(int32 framew, int32 frameh, int32 outerw, int32 outerh, b
|
||||||
request.outerh = outerh * factor;
|
request.outerh = outerh * factor;
|
||||||
request.rounded = rounded;
|
request.rounded = rounded;
|
||||||
_frames[0].request = _frames[1].request = _frames[2].request = request;
|
_frames[0].request = _frames[1].request = _frames[2].request = request;
|
||||||
_step.storeRelease(0); // start working
|
moveToNextShow();
|
||||||
_clipManagers.at(_threadIndex)->start(this);
|
_clipManagers.at(_threadIndex)->start(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,9 +344,8 @@ QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 oute
|
||||||
Frame *frame = frameToShow();
|
Frame *frame = frameToShow();
|
||||||
t_assert(frame != 0);
|
t_assert(frame != 0);
|
||||||
|
|
||||||
frame->displayed = true;
|
|
||||||
if (ms) {
|
if (ms) {
|
||||||
frame->when = ms;
|
frame->displayed.storeRelease(1);
|
||||||
if (_paused.loadAcquire()) {
|
if (_paused.loadAcquire()) {
|
||||||
_paused.storeRelease(0);
|
_paused.storeRelease(0);
|
||||||
if (_clipManagers.size() <= _threadIndex) error();
|
if (_clipManagers.size() <= _threadIndex) error();
|
||||||
|
@ -332,6 +353,8 @@ QPixmap ClipReader::current(int32 framew, int32 frameh, int32 outerw, int32 oute
|
||||||
_clipManagers.at(_threadIndex)->update(this);
|
_clipManagers.at(_threadIndex)->update(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
frame->displayed.storeRelease(-1); // displayed, but should be paused
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 factor(cIntRetinaFactor());
|
int32 factor(cIntRetinaFactor());
|
||||||
|
@ -412,7 +435,8 @@ public:
|
||||||
, _device(0)
|
, _device(0)
|
||||||
, _dataSize(0) {
|
, _dataSize(0) {
|
||||||
}
|
}
|
||||||
virtual bool readNextFrame(QImage &to, bool &hasAlpha, const QSize &size) = 0;
|
virtual bool readNextFrame() = 0;
|
||||||
|
virtual bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) = 0;
|
||||||
virtual int32 nextFrameDelay() = 0;
|
virtual int32 nextFrameDelay() = 0;
|
||||||
virtual bool start(bool onlyGifv) = 0;
|
virtual bool start(bool onlyGifv) = 0;
|
||||||
virtual ~ClipReaderImplementation() {
|
virtual ~ClipReaderImplementation() {
|
||||||
|
@ -459,30 +483,35 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage frame; // QGifHandler always reads first to internal QImage and returns it
|
_frame = QImage(); // QGifHandler always reads first to internal QImage and returns it
|
||||||
if (!_reader->read(&frame)) {
|
if (!_reader->read(&_frame) || _frame.isNull()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
--_framesLeft;
|
--_framesLeft;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (size.isEmpty() || size == frame.size()) {
|
bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) {
|
||||||
int32 w = frame.width(), h = frame.height();
|
t_assert(!_frame.isNull());
|
||||||
if (to.width() == w && to.height() == h && to.format() == frame.format()) {
|
if (size.isEmpty() || size == _frame.size()) {
|
||||||
if (to.byteCount() != frame.byteCount()) {
|
int32 w = _frame.width(), h = _frame.height();
|
||||||
int bpl = qMin(to.bytesPerLine(), frame.bytesPerLine());
|
if (to.width() == w && to.height() == h && to.format() == _frame.format()) {
|
||||||
|
if (to.byteCount() != _frame.byteCount()) {
|
||||||
|
int bpl = qMin(to.bytesPerLine(), _frame.bytesPerLine());
|
||||||
for (int i = 0; i < h; ++i) {
|
for (int i = 0; i < h; ++i) {
|
||||||
memcpy(to.scanLine(i), frame.constScanLine(i), bpl);
|
memcpy(to.scanLine(i), _frame.constScanLine(i), bpl);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
memcpy(to.bits(), frame.constBits(), frame.byteCount());
|
memcpy(to.bits(), _frame.constBits(), _frame.byteCount());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
to = frame.copy();
|
to = _frame.copy();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
to = frame.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
to = _frame.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
}
|
}
|
||||||
hasAlpha = frame.hasAlphaChannel();
|
hasAlpha = _frame.hasAlphaChannel();
|
||||||
|
_frame = QImage();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,6 +531,7 @@ public:
|
||||||
private:
|
private:
|
||||||
QImageReader *_reader;
|
QImageReader *_reader;
|
||||||
int32 _framesLeft, _frameDelay;
|
int32 _framesLeft, _frameDelay;
|
||||||
|
QImage _frame;
|
||||||
|
|
||||||
bool jumpToStart() {
|
bool jumpToStart() {
|
||||||
if (_reader && _reader->jumpToImage(0)) {
|
if (_reader && _reader->jumpToImage(0)) {
|
||||||
|
@ -540,6 +570,7 @@ public:
|
||||||
, _frame(0)
|
, _frame(0)
|
||||||
, _opened(false)
|
, _opened(false)
|
||||||
, _hadFrame(false)
|
, _hadFrame(false)
|
||||||
|
, _frameRead(false)
|
||||||
, _packetSize(0)
|
, _packetSize(0)
|
||||||
, _packetData(0)
|
, _packetData(0)
|
||||||
, _packetWas(false)
|
, _packetWas(false)
|
||||||
|
@ -555,7 +586,7 @@ public:
|
||||||
_avpkt.size = 0;
|
_avpkt.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool readNextFrame(QImage &to, bool &hasAlpha, const QSize &size) {
|
bool readNextFrame() {
|
||||||
int res;
|
int res;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (_avpkt.size > 0) { // previous packet not finished
|
if (_avpkt.size > 0) { // previous packet not finished
|
||||||
|
@ -607,56 +638,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (got_frame) {
|
if (got_frame) {
|
||||||
_hadFrame = true;
|
_hadFrame = _frameRead = true;
|
||||||
|
|
||||||
if (!_width || !_height) {
|
|
||||||
_width = _frame->width;
|
|
||||||
_height = _frame->height;
|
|
||||||
if (!_width || !_height) {
|
|
||||||
LOG(("Gif Error: Bad frame size %1").arg(logData()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QSize toSize(size.isEmpty() ? QSize(_width, _height) : size);
|
|
||||||
if (to.isNull() || to.size() != toSize) {
|
|
||||||
to = QImage(toSize, QImage::Format_ARGB32);
|
|
||||||
}
|
|
||||||
hasAlpha = (_frame->format == AV_PIX_FMT_BGRA || (_frame->format == -1 && _codecContext->pix_fmt == AV_PIX_FMT_BGRA));
|
|
||||||
if (_frame->width == toSize.width() && _frame->height == toSize.height() && hasAlpha) {
|
|
||||||
int32 sbpl = _frame->linesize[0], dbpl = to.bytesPerLine(), bpl = qMin(sbpl, dbpl);
|
|
||||||
uchar *s = _frame->data[0], *d = to.bits();
|
|
||||||
for (int32 i = 0, l = _frame->height; i < l; ++i) {
|
|
||||||
memcpy(d + i * dbpl, s + i * sbpl, bpl);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((_swsSize != toSize) || (_frame->format != -1 && _frame->format != _codecContext->pix_fmt) || !_swsContext) {
|
|
||||||
_swsSize = toSize;
|
|
||||||
_swsContext = sws_getCachedContext(_swsContext, _frame->width, _frame->height, AVPixelFormat(_frame->format), toSize.width(), toSize.height(), AV_PIX_FMT_BGRA, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
uint8_t * toData[1] = { to.bits() };
|
|
||||||
int toLinesize[1] = { to.bytesPerLine() };
|
|
||||||
if ((res = sws_scale(_swsContext, _frame->data, _frame->linesize, 0, _frame->height, toData, toLinesize)) != _swsSize.height()) {
|
|
||||||
LOG(("Gif Error: Unable to sws_scale to good size %1, height %2, should be %3").arg(logData()).arg(res).arg(_swsSize.height()));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 duration = av_frame_get_pkt_duration(_frame);
|
|
||||||
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
|
|
||||||
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
|
||||||
_currentFrameDelay = _nextFrameDelay;
|
|
||||||
if (_frameMs + _currentFrameDelay < frameMs) {
|
|
||||||
_currentFrameDelay = int32(frameMs - _frameMs);
|
|
||||||
}
|
|
||||||
if (duration == AV_NOPTS_VALUE) {
|
|
||||||
_nextFrameDelay = 0;
|
|
||||||
} else {
|
|
||||||
_nextFrameDelay = (duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
|
||||||
}
|
|
||||||
_frameMs = frameMs;
|
|
||||||
|
|
||||||
av_frame_unref(_frame);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,6 +663,61 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool renderFrame(QImage &to, bool &hasAlpha, const QSize &size) {
|
||||||
|
t_assert(_frameRead);
|
||||||
|
_frameRead = false;
|
||||||
|
|
||||||
|
if (!_width || !_height) {
|
||||||
|
_width = _frame->width;
|
||||||
|
_height = _frame->height;
|
||||||
|
if (!_width || !_height) {
|
||||||
|
LOG(("Gif Error: Bad frame size %1").arg(logData()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize toSize(size.isEmpty() ? QSize(_width, _height) : size);
|
||||||
|
if (to.isNull() || to.size() != toSize) {
|
||||||
|
to = QImage(toSize, QImage::Format_ARGB32);
|
||||||
|
}
|
||||||
|
hasAlpha = (_frame->format == AV_PIX_FMT_BGRA || (_frame->format == -1 && _codecContext->pix_fmt == AV_PIX_FMT_BGRA));
|
||||||
|
if (_frame->width == toSize.width() && _frame->height == toSize.height() && hasAlpha) {
|
||||||
|
int32 sbpl = _frame->linesize[0], dbpl = to.bytesPerLine(), bpl = qMin(sbpl, dbpl);
|
||||||
|
uchar *s = _frame->data[0], *d = to.bits();
|
||||||
|
for (int32 i = 0, l = _frame->height; i < l; ++i) {
|
||||||
|
memcpy(d + i * dbpl, s + i * sbpl, bpl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((_swsSize != toSize) || (_frame->format != -1 && _frame->format != _codecContext->pix_fmt) || !_swsContext) {
|
||||||
|
_swsSize = toSize;
|
||||||
|
_swsContext = sws_getCachedContext(_swsContext, _frame->width, _frame->height, AVPixelFormat(_frame->format), toSize.width(), toSize.height(), AV_PIX_FMT_BGRA, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
uint8_t * toData[1] = { to.bits() };
|
||||||
|
int toLinesize[1] = { to.bytesPerLine() }, res;
|
||||||
|
if ((res = sws_scale(_swsContext, _frame->data, _frame->linesize, 0, _frame->height, toData, toLinesize)) != _swsSize.height()) {
|
||||||
|
LOG(("Gif Error: Unable to sws_scale to good size %1, height %2, should be %3").arg(logData()).arg(res).arg(_swsSize.height()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int64 duration = av_frame_get_pkt_duration(_frame);
|
||||||
|
int64 framePts = (_frame->pkt_pts == AV_NOPTS_VALUE) ? _frame->pkt_dts : _frame->pkt_pts;
|
||||||
|
int64 frameMs = (framePts * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
|
_currentFrameDelay = _nextFrameDelay;
|
||||||
|
if (_frameMs + _currentFrameDelay < frameMs) {
|
||||||
|
_currentFrameDelay = int32(frameMs - _frameMs);
|
||||||
|
}
|
||||||
|
if (duration == AV_NOPTS_VALUE) {
|
||||||
|
_nextFrameDelay = 0;
|
||||||
|
} else {
|
||||||
|
_nextFrameDelay = (duration * 1000LL * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
|
}
|
||||||
|
_frameMs = frameMs;
|
||||||
|
|
||||||
|
av_frame_unref(_frame);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int32 nextFrameDelay() {
|
int32 nextFrameDelay() {
|
||||||
return _currentFrameDelay;
|
return _currentFrameDelay;
|
||||||
}
|
}
|
||||||
|
@ -776,7 +813,7 @@ private:
|
||||||
AVCodecContext *_codecContext;
|
AVCodecContext *_codecContext;
|
||||||
int32 _streamId;
|
int32 _streamId;
|
||||||
AVFrame *_frame;
|
AVFrame *_frame;
|
||||||
bool _opened, _hadFrame;
|
bool _opened, _hadFrame, _frameRead;
|
||||||
|
|
||||||
AVPacket _avpkt;
|
AVPacket _avpkt;
|
||||||
int _packetSize;
|
int _packetSize;
|
||||||
|
@ -835,9 +872,7 @@ public:
|
||||||
, _frame(0)
|
, _frame(0)
|
||||||
, _width(0)
|
, _width(0)
|
||||||
, _height(0)
|
, _height(0)
|
||||||
, _previousMs(0)
|
, _nextFrameWhen(0)
|
||||||
, _currentMs(0)
|
|
||||||
, _nextUpdateMs(0)
|
|
||||||
, _paused(false) {
|
, _paused(false) {
|
||||||
if (_data.isEmpty() && !_location->accessEnable()) {
|
if (_data.isEmpty() && !_location->accessEnable()) {
|
||||||
error();
|
error();
|
||||||
|
@ -851,7 +886,10 @@ public:
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
if (frame() && frame()->original.isNull()) {
|
if (frame() && frame()->original.isNull()) {
|
||||||
if (!_implementation->readNextFrame(frame()->original, frame()->alpha, QSize())) {
|
if (!_implementation->readNextFrame()) {
|
||||||
|
return error();
|
||||||
|
}
|
||||||
|
if (!_implementation->renderFrame(frame()->original, frame()->alpha, QSize())) {
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
_width = frame()->original.width();
|
_width = frame()->original.width();
|
||||||
|
@ -868,23 +906,22 @@ public:
|
||||||
return start(ms);
|
return start(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_paused && ms >= _nextUpdateMs) {
|
if (!_paused && ms >= _nextFrameWhen) {
|
||||||
return ClipProcessRepaint;
|
return ClipProcessRepaint;
|
||||||
}
|
}
|
||||||
return ClipProcessWait;
|
return ClipProcessWait;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipProcessResult finishProcess(uint64 ms) {
|
ClipProcessResult finishProcess(uint64 ms) {
|
||||||
_previousMs = _currentMs;
|
if (!readNextFrame()) {
|
||||||
if (!prepareNextFrame()) {
|
|
||||||
return error();
|
return error();
|
||||||
}
|
}
|
||||||
if (ms >= _nextUpdateMs) {
|
if (ms >= _nextFrameWhen && !readNextFrame(true)) {
|
||||||
if (!prepareNextFrame()) {
|
return error();
|
||||||
return error();
|
}
|
||||||
}
|
if (!renderFrame()) {
|
||||||
|
return error();
|
||||||
}
|
}
|
||||||
_currentMs = qMax(ms, _nextUpdateMs);
|
|
||||||
return ClipProcessCopyFrame;
|
return ClipProcessCopyFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -893,15 +930,26 @@ public:
|
||||||
return qMax(delay, 5);
|
return qMax(delay, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool prepareNextFrame() {
|
bool readNextFrame(bool keepup = false) {
|
||||||
t_assert(frame() != 0 && _request.valid());
|
if (!_implementation->readNextFrame()) {
|
||||||
if (!_implementation->readNextFrame(frame()->original, frame()->alpha, QSize(_request.framew, _request.frameh))) {
|
return false;
|
||||||
|
}
|
||||||
|
_nextFrameWhen += nextFrameDelay();
|
||||||
|
if (keepup) {
|
||||||
|
_nextFrameWhen = qMax(_nextFrameWhen, getms());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renderFrame() {
|
||||||
|
t_assert(frame() != 0 && _request.valid());
|
||||||
|
if (!_implementation->renderFrame(frame()->original, frame()->alpha, QSize(_request.framew, _request.frameh))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_nextUpdateMs = _currentMs + nextFrameDelay();
|
|
||||||
frame()->original.setDevicePixelRatio(_request.factor);
|
frame()->original.setDevicePixelRatio(_request.factor);
|
||||||
frame()->pix = QPixmap();
|
frame()->pix = QPixmap();
|
||||||
frame()->pix = _prepareFrame(_request, frame()->original, frame()->alpha, frame()->cache);
|
frame()->pix = _prepareFrame(_request, frame()->original, frame()->alpha, frame()->cache);
|
||||||
|
frame()->when = _nextFrameWhen;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,11 +1010,12 @@ private:
|
||||||
|
|
||||||
ClipFrameRequest _request;
|
ClipFrameRequest _request;
|
||||||
struct Frame {
|
struct Frame {
|
||||||
Frame() : alpha(true) {
|
Frame() : alpha(true), when(0) {
|
||||||
}
|
}
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
QImage original, cache;
|
QImage original, cache;
|
||||||
bool alpha;
|
bool alpha;
|
||||||
|
uint64 when;
|
||||||
};
|
};
|
||||||
Frame _frames[3];
|
Frame _frames[3];
|
||||||
int32 _frame;
|
int32 _frame;
|
||||||
|
@ -976,7 +1025,7 @@ private:
|
||||||
|
|
||||||
int32 _width, _height;
|
int32 _width, _height;
|
||||||
|
|
||||||
uint64 _previousMs, _currentMs, _nextUpdateMs;
|
uint64 _nextFrameWhen;
|
||||||
|
|
||||||
bool _paused;
|
bool _paused;
|
||||||
|
|
||||||
|
@ -1070,13 +1119,16 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
|
||||||
if (result == ClipProcessStarted) {
|
if (result == ClipProcessStarted) {
|
||||||
_loadLevel.fetchAndAddRelaxed(reader->_width * reader->_height - AverageGifSize);
|
_loadLevel.fetchAndAddRelaxed(reader->_width * reader->_height - AverageGifSize);
|
||||||
}
|
}
|
||||||
if (!reader->_paused && (result == ClipProcessRepaint || result == ClipProcessWait)) {
|
if (!reader->_paused && result == ClipProcessRepaint) {
|
||||||
ClipReader::Frame *other = it.key()->frameToWriteNext(false);
|
int32 ishowing, iprevious;
|
||||||
t_assert(other != 0);
|
ClipReader::Frame *showing = it.key()->frameToShow(&ishowing), *previous = it.key()->frameToWriteNext(false, &iprevious);
|
||||||
if (other->when && other->when + WaitBeforeGifPause < qMax(reader->_previousMs, ms)) {
|
t_assert(previous != 0 && showing != 0 && ishowing >= 0 && iprevious >= 0);
|
||||||
reader->_paused = true;
|
if (reader->_frames[ishowing].when > 0 && showing->displayed.loadAcquire() <= 0) { // current frame was not shown
|
||||||
it.key()->_paused.storeRelease(1);
|
if (reader->_frames[ishowing].when + WaitBeforeGifPause < ms || (reader->_frames[iprevious].when && previous->displayed.loadAcquire() <= 0)) {
|
||||||
result = ClipProcessPaused;
|
reader->_paused = true;
|
||||||
|
it.key()->_paused.storeRelease(1);
|
||||||
|
result = ClipProcessPaused;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == ClipProcessStarted || result == ClipProcessCopyFrame) {
|
if (result == ClipProcessStarted || result == ClipProcessCopyFrame) {
|
||||||
|
@ -1085,14 +1137,17 @@ bool ClipReadManager::handleProcessResult(ClipReaderPrivate *reader, ClipProcess
|
||||||
frame->clear();
|
frame->clear();
|
||||||
frame->pix = reader->frame()->pix;
|
frame->pix = reader->frame()->pix;
|
||||||
frame->original = reader->frame()->original;
|
frame->original = reader->frame()->original;
|
||||||
frame->displayed = false;
|
frame->displayed.storeRelease(0);
|
||||||
it.key()->moveToNextWrite();
|
|
||||||
if (result == ClipProcessStarted) {
|
if (result == ClipProcessStarted) {
|
||||||
|
reader->_nextFrameWhen = ms;
|
||||||
|
it.key()->moveToNextWrite();
|
||||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
||||||
}
|
}
|
||||||
} else if (result == ClipProcessPaused) {
|
} else if (result == ClipProcessPaused) {
|
||||||
|
it.key()->moveToNextWrite();
|
||||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
emit callback(it.key(), it.key()->threadIndex(), ClipReaderReinit);
|
||||||
} else if (result == ClipProcessRepaint) {
|
} else if (result == ClipProcessRepaint) {
|
||||||
|
it.key()->moveToNextWrite();
|
||||||
emit callback(it.key(), it.key()->threadIndex(), ClipReaderRepaint);
|
emit callback(it.key(), it.key()->threadIndex(), ClipReaderRepaint);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1174,7 +1229,7 @@ void ClipReadManager::process() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ms = getms();
|
ms = getms();
|
||||||
i.value() = reader->_nextUpdateMs ? reader->_nextUpdateMs : (ms + 86400 * 1000ULL);
|
i.value() = reader->_nextFrameWhen ? reader->_nextFrameWhen : (ms + 86400 * 1000ULL);
|
||||||
}
|
}
|
||||||
if (!reader->_paused && i.value() < minms) {
|
if (!reader->_paused && i.value() < minms) {
|
||||||
minms = i.value();
|
minms = i.value();
|
||||||
|
@ -1224,7 +1279,7 @@ MTPDocumentAttribute clipReadAnimatedAttributes(const QString &fname, const QByt
|
||||||
FFMpegReaderImplementation *reader = new FFMpegReaderImplementation(&localloc, &localdata);
|
FFMpegReaderImplementation *reader = new FFMpegReaderImplementation(&localloc, &localdata);
|
||||||
if (reader->start(true)) {
|
if (reader->start(true)) {
|
||||||
bool hasAlpha = false;
|
bool hasAlpha = false;
|
||||||
if (reader->readNextFrame(cover, hasAlpha, QSize())) {
|
if (reader->readNextFrame() && reader->renderFrame(cover, hasAlpha, QSize())) {
|
||||||
if (cover.width() > 0 && cover.height() > 0 && cover.width() < cover.height() * 10 && cover.height() < cover.width() * 10) {
|
if (cover.width() > 0 && cover.height() > 0 && cover.width() < cover.height() * 10 && cover.height() < cover.width() * 10) {
|
||||||
if (hasAlpha) {
|
if (hasAlpha) {
|
||||||
QImage cacheForResize;
|
QImage cacheForResize;
|
||||||
|
|
|
@ -497,8 +497,9 @@ enum ClipReaderNotification {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ClipReaderSteps {
|
enum ClipReaderSteps {
|
||||||
FirstFrameNotReadStep = -2,
|
WaitingForDimensionsStep = -3, // before ClipReaderPrivate read the first image and got the original frame size
|
||||||
WaitingForRequestStep = -1,
|
WaitingForRequestStep = -2, // before ClipReader got the original frame size and prepared the frame request
|
||||||
|
WaitingForFirstFrameStep = -1, // before ClipReaderPrivate got the frame request and started waiting for the 1-2 delay
|
||||||
};
|
};
|
||||||
|
|
||||||
class ClipReaderPrivate;
|
class ClipReaderPrivate;
|
||||||
|
@ -528,7 +529,7 @@ public:
|
||||||
}
|
}
|
||||||
bool currentDisplayed() const {
|
bool currentDisplayed() const {
|
||||||
Frame *frame = frameToShow();
|
Frame *frame = frameToShow();
|
||||||
return frame ? frame->displayed : true;
|
return frame ? (frame->displayed.loadAcquire() != 0) : true;
|
||||||
}
|
}
|
||||||
bool paused() const {
|
bool paused() const {
|
||||||
return _paused.loadAcquire();
|
return _paused.loadAcquire();
|
||||||
|
@ -542,7 +543,8 @@ public:
|
||||||
|
|
||||||
ClipState state() const;
|
ClipState state() const;
|
||||||
bool started() const {
|
bool started() const {
|
||||||
return _step.loadAcquire() >= 0;
|
int32 step = _step.loadAcquire();
|
||||||
|
return (step == WaitingForFirstFrameStep) || (step >= 0);
|
||||||
}
|
}
|
||||||
bool ready() const;
|
bool ready() const;
|
||||||
|
|
||||||
|
@ -561,7 +563,7 @@ private:
|
||||||
|
|
||||||
mutable QAtomicInt _step; // -2, -1 - init, 0-5 - work, show ((state + 1) / 2) % 3 state, write ((state + 3) / 2) % 3
|
mutable QAtomicInt _step; // -2, -1 - init, 0-5 - work, show ((state + 1) / 2) % 3 state, write ((state + 3) / 2) % 3
|
||||||
struct Frame {
|
struct Frame {
|
||||||
Frame() : displayed(false), when(0) {
|
Frame() : displayed(false) {
|
||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
pix = QPixmap();
|
pix = QPixmap();
|
||||||
|
@ -570,13 +572,12 @@ private:
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
QImage original;
|
QImage original;
|
||||||
ClipFrameRequest request;
|
ClipFrameRequest request;
|
||||||
bool displayed;
|
QAtomicInt displayed;
|
||||||
uint64 when;
|
|
||||||
};
|
};
|
||||||
mutable Frame _frames[3];
|
mutable Frame _frames[3];
|
||||||
Frame *frameToShow() const; // 0 means not ready
|
Frame *frameToShow(int32 *index = 0) const; // 0 means not ready
|
||||||
Frame *frameToWrite(int32 *index = 0) const; // 0 means not ready
|
Frame *frameToWrite(int32 *index = 0) const; // 0 means not ready
|
||||||
Frame *frameToWriteNext(bool check) const;
|
Frame *frameToWriteNext(bool check, int32 *index = 0) const;
|
||||||
void moveToNextShow() const;
|
void moveToNextShow() const;
|
||||||
void moveToNextWrite() const;
|
void moveToNextWrite() const;
|
||||||
|
|
||||||
|
|
|
@ -1392,7 +1392,9 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
|
||||||
case mtpc_messageMediaUnsupported:
|
case mtpc_messageMediaUnsupported:
|
||||||
default: badMedia = 1; break;
|
default: badMedia = 1; break;
|
||||||
}
|
}
|
||||||
if (badMedia) {
|
if (false && badMedia == 1) {
|
||||||
|
// QString text(lng_message_unsupported(lt_link, qsl("https://desktop.telegram.org")));
|
||||||
|
} else if (badMedia) {
|
||||||
result = new HistoryServiceMsg(this, block, m.vid.v, date(m.vdate), lang((badMedia == 2) ? lng_message_empty : lng_media_unsupported), m.vflags.v, 0, m.has_from_id() ? m.vfrom_id.v : 0);
|
result = new HistoryServiceMsg(this, block, m.vid.v, date(m.vdate), lang((badMedia == 2) ? lng_message_empty : lng_media_unsupported), m.vflags.v, 0, m.has_from_id() ? m.vfrom_id.v : 0);
|
||||||
} else {
|
} else {
|
||||||
if ((m.has_fwd_date() && m.vfwd_date.v > 0) || (m.has_fwd_from_id() && peerFromMTP(m.vfwd_from_id) != 0)) {
|
if ((m.has_fwd_date() && m.vfwd_date.v > 0) || (m.has_fwd_from_id() && peerFromMTP(m.vfwd_from_id) != 0)) {
|
||||||
|
@ -3352,11 +3354,16 @@ void HistoryPhoto::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
|
||||||
p.setOpacity(radialOpacity);
|
p.setOpacity(radialOpacity);
|
||||||
style::sprite icon;
|
style::sprite icon;
|
||||||
if (radial || _data->loading()) {
|
if (radial || _data->loading()) {
|
||||||
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
DelayedStorageImage *delayed = _data->full->toDelayedStorageImage();
|
||||||
|
if (!delayed || !delayed->location().isNull()) {
|
||||||
|
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
|
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
|
||||||
}
|
}
|
||||||
p.drawSpriteCenter(inner, icon);
|
if (!icon.isEmpty()) {
|
||||||
|
p.drawSpriteCenter(inner, icon);
|
||||||
|
}
|
||||||
if (radial) {
|
if (radial) {
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||||
|
@ -3401,8 +3408,15 @@ void HistoryPhoto::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
|
||||||
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
|
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
|
||||||
if (_data->uploading()) {
|
if (_data->uploading()) {
|
||||||
lnk = _cancell;
|
lnk = _cancell;
|
||||||
|
} else if (_data->loaded()) {
|
||||||
|
lnk = _openl;
|
||||||
|
} else if (_data->loading()) {
|
||||||
|
DelayedStorageImage *delayed = _data->full->toDelayedStorageImage();
|
||||||
|
if (!delayed || !delayed->location().isNull()) {
|
||||||
|
lnk = _cancell;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
lnk = _data->loaded() ? _openl : (_data->loading() ? _cancell : _savel);
|
lnk = _savel;
|
||||||
}
|
}
|
||||||
if (_caption.isEmpty() && parent->getMedia() == this) {
|
if (_caption.isEmpty() && parent->getMedia() == this) {
|
||||||
int32 fullRight = skipx + width, fullBottom = skipy + height;
|
int32 fullRight = skipx + width, fullBottom = skipy + height;
|
||||||
|
@ -4561,11 +4575,15 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
|
||||||
if (_data->loaded() && !radial) {
|
if (_data->loaded() && !radial) {
|
||||||
icon = (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
|
icon = (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
|
||||||
} else if (radial || _data->loading()) {
|
} else if (radial || _data->loading()) {
|
||||||
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
if (parent->id > 0) {
|
||||||
|
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
|
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
|
||||||
}
|
}
|
||||||
p.drawSpriteCenter(inner, icon);
|
if (!icon.isEmpty()) {
|
||||||
|
p.drawSpriteCenter(inner, icon);
|
||||||
|
}
|
||||||
if (radial) {
|
if (radial) {
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||||
|
@ -4762,6 +4780,16 @@ void HistorySticker::initDimensions(const HistoryItem *parent) {
|
||||||
_height = _minh;
|
_height = _minh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 HistorySticker::resize(int32 width, const HistoryItem *parent) { // return new height
|
||||||
|
_width = qMin(width, _maxw);
|
||||||
|
if (const HistoryReply *reply = toHistoryReply(parent)) {
|
||||||
|
int32 usew = _maxw - st::msgReplyPadding.left() - reply->replyToWidth();
|
||||||
|
int32 rw = _width - usew - st::msgReplyPadding.left() - st::msgReplyPadding.left() - st::msgReplyPadding.right();
|
||||||
|
reply->resizeVia(rw);
|
||||||
|
}
|
||||||
|
return _height;
|
||||||
|
}
|
||||||
|
|
||||||
void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const {
|
void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const {
|
||||||
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||||
|
|
||||||
|
@ -5958,7 +5986,7 @@ void ViaInlineBotLink::onClick(Qt::MouseButton button) const {
|
||||||
HistoryMessageVia::HistoryMessageVia(int32 userId)
|
HistoryMessageVia::HistoryMessageVia(int32 userId)
|
||||||
: bot(App::userLoaded(peerFromUser(userId)))
|
: bot(App::userLoaded(peerFromUser(userId)))
|
||||||
, width(0)
|
, width(0)
|
||||||
, fullWidth(st::msgServiceNameFont->width(qsl("via @") + bot->username))
|
, maxWidth(st::msgServiceNameFont->width(qsl("via @") + bot->username))
|
||||||
, lnk(new ViaInlineBotLink(bot)) {
|
, lnk(new ViaInlineBotLink(bot)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5967,13 +5995,21 @@ bool HistoryMessageVia::isNull() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessageVia::resize(int32 availw) {
|
void HistoryMessageVia::resize(int32 availw) {
|
||||||
if (width < fullWidth && availw > width) {
|
if (width < maxWidth && availw > width) {
|
||||||
if (availw < fullWidth) {
|
if (availw < maxWidth) {
|
||||||
text = st::msgServiceNameFont->elided(qsl("via @") + bot->username, availw);
|
text = st::msgServiceNameFont->elided(qsl("via @") + bot->username, availw);
|
||||||
width = st::msgServiceNameFont->width(text);
|
width = st::msgServiceNameFont->width(text);
|
||||||
} else {
|
} else {
|
||||||
text = qsl("via @") + bot->username;
|
text = qsl("via @") + bot->username;
|
||||||
width = fullWidth;
|
width = maxWidth;
|
||||||
|
}
|
||||||
|
} else if (availw < width) {
|
||||||
|
if (availw > 0) {
|
||||||
|
text = st::msgServiceNameFont->elided(qsl("via @") + bot->username, availw);
|
||||||
|
width = st::msgServiceNameFont->width(text);
|
||||||
|
} else {
|
||||||
|
text = QString();
|
||||||
|
width = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6165,9 +6201,9 @@ void HistoryMessage::initDimensions() {
|
||||||
if (maxw > _maxw) _maxw = maxw;
|
if (maxw > _maxw) _maxw = maxw;
|
||||||
_minh += _media->minHeight();
|
_minh += _media->minHeight();
|
||||||
}
|
}
|
||||||
if (via()) {
|
if (!_media && !displayFromName() && via() && !toHistoryForwarded()) {
|
||||||
if (st::msgPadding.left() + via()->fullWidth + st::msgPadding.right() > _maxw) {
|
if (st::msgPadding.left() + via()->maxWidth + st::msgPadding.right() > _maxw) {
|
||||||
_maxw = st::msgPadding.left() + via()->fullWidth + st::msgPadding.right() > _maxw;
|
_maxw = st::msgPadding.left() + via()->maxWidth + st::msgPadding.right();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -6200,8 +6236,11 @@ void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const {
|
||||||
|
|
||||||
void HistoryMessage::fromNameUpdated() const {
|
void HistoryMessage::fromNameUpdated() const {
|
||||||
if (!_media && displayFromName()) {
|
if (!_media && displayFromName()) {
|
||||||
int32 _namew = st::msgPadding.left() + _from->nameText.maxWidth() + st::msgPadding.right();
|
int32 namew = st::msgPadding.left() + _from->nameText.maxWidth() + st::msgPadding.right();
|
||||||
if (_namew > _maxw) _maxw = _namew;
|
if (via() && !toHistoryForwarded()) {
|
||||||
|
namew += st::msgServiceFont->spacew + via()->maxWidth;
|
||||||
|
}
|
||||||
|
if (namew > _maxw) _maxw = namew;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6437,7 +6476,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_from->nameVersion > _fromVersion) {
|
if (_from->nameVersion > _fromVersion) {
|
||||||
fromNameUpdated();
|
// fromNameUpdated();
|
||||||
_fromVersion = _from->nameVersion;
|
_fromVersion = _from->nameVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6464,6 +6503,10 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
||||||
p.setPen(_from->color);
|
p.setPen(_from->color);
|
||||||
}
|
}
|
||||||
_from->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right());
|
_from->nameText.drawElided(p, r.left() + st::msgPadding.left(), r.top() + st::msgPadding.top(), width - st::msgPadding.left() - st::msgPadding.right());
|
||||||
|
if (via() && !toHistoryForwarded() && width > st::msgPadding.left() + st::msgPadding.right() + _from->nameText.maxWidth() + st::msgServiceFont->spacew) {
|
||||||
|
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
|
||||||
|
p.drawText(r.left() + st::msgPadding.left() + _from->nameText.maxWidth() + st::msgServiceFont->spacew, r.top() + st::msgPadding.top() + st::msgServiceFont->ascent, via()->text);
|
||||||
|
}
|
||||||
r.setTop(r.top() + st::msgNameFont->height);
|
r.setTop(r.top() + st::msgNameFont->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6495,15 +6538,15 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
|
||||||
|
|
||||||
void HistoryMessage::drawMessageText(Painter &p, QRect trect, uint32 selection) const {
|
void HistoryMessage::drawMessageText(Painter &p, QRect trect, uint32 selection) const {
|
||||||
bool outbg = out() && !fromChannel(), selected = (selection == FullSelection);
|
bool outbg = out() && !fromChannel(), selected = (selection == FullSelection);
|
||||||
if (via()) {
|
if (!displayFromName() && via() && !toHistoryForwarded()) {
|
||||||
p.setFont(st::msgServiceNameFont);
|
p.setFont(st::msgServiceNameFont);
|
||||||
p.setPen((selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg))->p);
|
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
|
||||||
p.drawTextLeft(trect.left(), trect.top(), _history->width, via()->text);
|
p.drawTextLeft(trect.left(), trect.top(), _history->width, via()->text);
|
||||||
trect.setY(trect.y() + st::msgServiceNameFont->height);
|
trect.setY(trect.y() + st::msgServiceNameFont->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen(st::msgColor->p);
|
p.setPen(st::msgColor);
|
||||||
p.setFont(st::msgFont->f);
|
p.setFont(st::msgFont);
|
||||||
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
|
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
|
||||||
uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF;
|
uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF;
|
||||||
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignLeft, 0, -1, selectedFrom, selectedTo);
|
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignLeft, 0, -1, selectedFrom, selectedTo);
|
||||||
|
@ -6549,8 +6592,10 @@ int32 HistoryMessage::resize(int32 width) {
|
||||||
} else {
|
} else {
|
||||||
_height += st::msgNameFont->height;
|
_height += st::msgNameFont->height;
|
||||||
}
|
}
|
||||||
}
|
if (via() && !toHistoryForwarded()) {
|
||||||
if (via()) {
|
via()->resize(width - st::msgPadding.left() - st::msgPadding.right() - _from->nameText.maxWidth() - st::msgServiceFont->spacew);
|
||||||
|
}
|
||||||
|
} else if (via() && !toHistoryForwarded()) {
|
||||||
via()->resize(width - st::msgPadding.left() - st::msgPadding.right());
|
via()->resize(width - st::msgPadding.left() - st::msgPadding.right());
|
||||||
if (emptyText() && !displayFromName()) {
|
if (emptyText() && !displayFromName()) {
|
||||||
_height += st::msgPadding.top() + st::msgNameFont->height + st::mediaHeaderSkip;
|
_height += st::msgPadding.top() + st::msgNameFont->height + st::mediaHeaderSkip;
|
||||||
|
@ -6612,9 +6657,15 @@ void HistoryMessage::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32
|
||||||
if (drawBubble()) {
|
if (drawBubble()) {
|
||||||
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
|
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
|
||||||
if (displayFromName()) { // from user left name
|
if (displayFromName()) { // from user left name
|
||||||
if (x >= r.left() + st::msgPadding.left() && y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth()) {
|
if (y >= r.top() + st::msgPadding.top() && y < r.top() + st::msgPadding.top() + st::msgNameFont->height) {
|
||||||
lnk = _from->lnk;
|
if (x >= r.left() + st::msgPadding.left() && x < r.left() + r.width() - st::msgPadding.right() && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth()) {
|
||||||
return;
|
lnk = _from->lnk;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (via() && !toHistoryForwarded() && x >= r.left() + st::msgPadding.left() + _from->nameText.maxWidth() + st::msgServiceFont->spacew && x < r.left() + st::msgPadding.left() + _from->nameText.maxWidth() + st::msgServiceFont->spacew + via()->width) {
|
||||||
|
lnk = via()->lnk;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
r.setTop(r.top() + st::msgNameFont->height);
|
r.setTop(r.top() + st::msgNameFont->height);
|
||||||
}
|
}
|
||||||
|
@ -6629,7 +6680,7 @@ void HistoryMessage::getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorStat
|
||||||
|
|
||||||
QRect trect(r.marginsAdded(-st::msgPadding));
|
QRect trect(r.marginsAdded(-st::msgPadding));
|
||||||
|
|
||||||
if (via()) {
|
if (!displayFromName() && via() && !toHistoryForwarded()) {
|
||||||
if (x >= trect.left() && y >= trect.top() && y < trect.top() + st::msgNameFont->height && x < trect.left() + via()->width) {
|
if (x >= trect.left() && y >= trect.top() && y < trect.top() + st::msgNameFont->height && x < trect.left() + via()->width) {
|
||||||
lnk = via()->lnk;
|
lnk = via()->lnk;
|
||||||
return;
|
return;
|
||||||
|
@ -6678,8 +6729,7 @@ void HistoryMessage::getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x,
|
||||||
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
|
QRect r(left, st::msgMargin.top(), width, _height - st::msgMargin.top() - st::msgMargin.bottom());
|
||||||
if (displayFromName()) { // from user left name
|
if (displayFromName()) { // from user left name
|
||||||
r.setTop(r.top() + st::msgNameFont->height);
|
r.setTop(r.top() + st::msgNameFont->height);
|
||||||
}
|
} else if (via() && !toHistoryForwarded()) {
|
||||||
if (via()) {
|
|
||||||
r.setTop(r.top() + st::msgNameFont->height);
|
r.setTop(r.top() + st::msgNameFont->height);
|
||||||
}
|
}
|
||||||
QRect trect(r.marginsAdded(-st::msgPadding));
|
QRect trect(r.marginsAdded(-st::msgPadding));
|
||||||
|
@ -6765,12 +6815,16 @@ void HistoryForwarded::initDimensions() {
|
||||||
HistoryMessage::initDimensions();
|
HistoryMessage::initDimensions();
|
||||||
if (!_media) {
|
if (!_media) {
|
||||||
int32 _namew = st::msgPadding.left() + fromWidth + fwdFromName.maxWidth() + st::msgPadding.right();
|
int32 _namew = st::msgPadding.left() + fromWidth + fwdFromName.maxWidth() + st::msgPadding.right();
|
||||||
|
if (via()) {
|
||||||
|
_namew += st::msgServiceFont->spacew + via()->maxWidth;
|
||||||
|
}
|
||||||
if (_namew > _maxw) _maxw = _namew;
|
if (_namew > _maxw) _maxw = _namew;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryForwarded::fwdNameUpdated() const {
|
void HistoryForwarded::fwdNameUpdated() const {
|
||||||
fwdFromName.setText(st::msgServiceNameFont, App::peerName(fwdFrom), _textNameOptions);
|
QString fwdName((via() && fwdFrom->isUser()) ? fwdFrom->asUser()->firstName : App::peerName(fwdFrom));
|
||||||
|
fwdFromName.setText(st::msgServiceNameFont, fwdName, _textNameOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryForwarded::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const {
|
void HistoryForwarded::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const {
|
||||||
|
@ -6788,10 +6842,17 @@ void HistoryForwarded::drawForwardedFrom(Painter &p, int32 x, int32 y, int32 w,
|
||||||
p.setPen((selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg))->p);
|
p.setPen((selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg))->p);
|
||||||
p.setFont(serviceFont);
|
p.setFont(serviceFont);
|
||||||
|
|
||||||
if (w >= fromWidth) {
|
if (via() && w > fromWidth + fwdFromName.maxWidth() + serviceFont->spacew) {
|
||||||
p.drawText(x, y + serviceFont->ascent, lang(lng_forwarded_from));
|
p.drawText(x, y + serviceFont->ascent, lang(lng_forwarded_from));
|
||||||
|
|
||||||
p.setFont(serviceName->f);
|
p.setFont(serviceName);
|
||||||
|
fwdFromName.draw(p, x + fromWidth, y, w - fromWidth);
|
||||||
|
|
||||||
|
p.drawText(x + fromWidth + fwdFromName.maxWidth() + serviceFont->spacew, y + serviceFont->ascent, via()->text);
|
||||||
|
} else if (w > fromWidth) {
|
||||||
|
p.drawText(x, y + serviceFont->ascent, lang(lng_forwarded_from));
|
||||||
|
|
||||||
|
p.setFont(serviceName);
|
||||||
fwdFromName.drawElided(p, x + fromWidth, y, w - fromWidth);
|
fwdFromName.drawElided(p, x + fromWidth, y, w - fromWidth);
|
||||||
} else {
|
} else {
|
||||||
p.drawText(x, y + serviceFont->ascent, serviceFont->elided(lang(lng_forwarded_from), w));
|
p.drawText(x, y + serviceFont->ascent, serviceFont->elided(lang(lng_forwarded_from), w));
|
||||||
|
@ -6810,11 +6871,14 @@ int32 HistoryForwarded::resize(int32 width) {
|
||||||
HistoryMessage::resize(width);
|
HistoryMessage::resize(width);
|
||||||
if (drawBubble()) {
|
if (drawBubble()) {
|
||||||
if (displayForwardedFrom()) {
|
if (displayForwardedFrom()) {
|
||||||
if (emptyText() && !displayFromName() && !via()) {
|
if (emptyText() && !displayFromName()) {
|
||||||
_height += st::msgPadding.top() + st::msgServiceNameFont->height + st::mediaHeaderSkip;
|
_height += st::msgPadding.top() + st::msgServiceNameFont->height + st::mediaHeaderSkip;
|
||||||
} else {
|
} else {
|
||||||
_height += st::msgServiceNameFont->height;
|
_height += st::msgServiceNameFont->height;
|
||||||
}
|
}
|
||||||
|
if (via()) {
|
||||||
|
via()->resize(width - st::msgPadding.left() - st::msgPadding.right() - fromWidth - fwdFromName.maxWidth() - st::msgServiceFont->spacew);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return _height;
|
return _height;
|
||||||
|
@ -6876,6 +6940,8 @@ void HistoryForwarded::getForwardedState(TextLinkPtr &lnk, HistoryCursorState &s
|
||||||
state = HistoryDefaultCursorState;
|
state = HistoryDefaultCursorState;
|
||||||
if (x >= fromWidth && x < w && x < fromWidth + fwdFromName.maxWidth()) {
|
if (x >= fromWidth && x < w && x < fromWidth + fwdFromName.maxWidth()) {
|
||||||
lnk = fwdFrom->lnk;
|
lnk = fwdFrom->lnk;
|
||||||
|
} else if (via() && x >= fromWidth + fwdFromName.maxWidth() + st::msgServiceFont->spacew && x < w && x < fromWidth + fwdFromName.maxWidth() + st::msgServiceFont->spacew + via()->maxWidth) {
|
||||||
|
lnk = via()->lnk;
|
||||||
} else {
|
} else {
|
||||||
lnk = TextLinkPtr();
|
lnk = TextLinkPtr();
|
||||||
}
|
}
|
||||||
|
@ -6910,7 +6976,8 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, const MTPDmess
|
||||||
, replyToMsgId(msg.vreply_to_msg_id.v)
|
, replyToMsgId(msg.vreply_to_msg_id.v)
|
||||||
, replyToMsg(0)
|
, replyToMsg(0)
|
||||||
, replyToVersion(0)
|
, replyToVersion(0)
|
||||||
, _maxReplyWidth(0) {
|
, _maxReplyWidth(0)
|
||||||
|
, _replyToVia(0) {
|
||||||
if (!updateReplyTo() && App::api()) {
|
if (!updateReplyTo() && App::api()) {
|
||||||
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
||||||
}
|
}
|
||||||
|
@ -6921,7 +6988,8 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i
|
||||||
, replyToMsgId(replyTo)
|
, replyToMsgId(replyTo)
|
||||||
, replyToMsg(0)
|
, replyToMsg(0)
|
||||||
, replyToVersion(0)
|
, replyToVersion(0)
|
||||||
, _maxReplyWidth(0) {
|
, _maxReplyWidth(0)
|
||||||
|
, _replyToVia(0) {
|
||||||
if (!updateReplyTo() && App::api()) {
|
if (!updateReplyTo() && App::api()) {
|
||||||
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
||||||
}
|
}
|
||||||
|
@ -6932,7 +7000,8 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i
|
||||||
, replyToMsgId(replyTo)
|
, replyToMsgId(replyTo)
|
||||||
, replyToMsg(0)
|
, replyToMsg(0)
|
||||||
, replyToVersion(0)
|
, replyToVersion(0)
|
||||||
, _maxReplyWidth(0) {
|
, _maxReplyWidth(0)
|
||||||
|
, _replyToVia(0) {
|
||||||
if (!updateReplyTo() && App::api()) {
|
if (!updateReplyTo() && App::api()) {
|
||||||
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
App::api()->requestReplyTo(this, history->peer->asChannel(), replyToMsgId);
|
||||||
}
|
}
|
||||||
|
@ -6952,6 +7021,9 @@ void HistoryReply::initDimensions() {
|
||||||
HistoryMessage::initDimensions();
|
HistoryMessage::initDimensions();
|
||||||
if (!_media) {
|
if (!_media) {
|
||||||
int32 replyw = st::msgPadding.left() + _maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right();
|
int32 replyw = st::msgPadding.left() + _maxReplyWidth - st::msgReplyPadding.left() - st::msgReplyPadding.right() + st::msgPadding.right();
|
||||||
|
if (replyToVia()) {
|
||||||
|
replyw += st::msgServiceFont->spacew + via()->maxWidth;
|
||||||
|
}
|
||||||
if (replyw > _maxw) _maxw = replyw;
|
if (replyw > _maxw) _maxw = replyw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6959,6 +7031,7 @@ void HistoryReply::initDimensions() {
|
||||||
bool HistoryReply::updateReplyTo(bool force) {
|
bool HistoryReply::updateReplyTo(bool force) {
|
||||||
if (replyToMsg || !replyToMsgId) return true;
|
if (replyToMsg || !replyToMsgId) return true;
|
||||||
replyToMsg = App::histItemById(channelId(), replyToMsgId);
|
replyToMsg = App::histItemById(channelId(), replyToMsgId);
|
||||||
|
|
||||||
if (replyToMsg) {
|
if (replyToMsg) {
|
||||||
App::historyRegReply(this, replyToMsg);
|
App::historyRegReply(this, replyToMsg);
|
||||||
replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
|
replyToText.setText(st::msgFont, replyToMsg->inReplyText(), _textDlgOptions);
|
||||||
|
@ -6966,6 +7039,11 @@ bool HistoryReply::updateReplyTo(bool force) {
|
||||||
replyToNameUpdated();
|
replyToNameUpdated();
|
||||||
|
|
||||||
replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id));
|
replyToLnk = TextLinkPtr(new MessageLink(replyToMsg->history()->peer->id, replyToMsg->id));
|
||||||
|
if (!replyToMsg->toHistoryForwarded()) {
|
||||||
|
if (UserData *bot = replyToMsg->viaBot()) {
|
||||||
|
_replyToVia = new HistoryMessageVia(peerToUser(bot->id));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (force) {
|
} else if (force) {
|
||||||
replyToMsgId = 0;
|
replyToMsgId = 0;
|
||||||
}
|
}
|
||||||
|
@ -6978,12 +7056,17 @@ bool HistoryReply::updateReplyTo(bool force) {
|
||||||
|
|
||||||
void HistoryReply::replyToNameUpdated() const {
|
void HistoryReply::replyToNameUpdated() const {
|
||||||
if (replyToMsg) {
|
if (replyToMsg) {
|
||||||
replyToName.setText(st::msgServiceNameFont, App::peerName(replyToMsg->from()), _textNameOptions);
|
QString name = (replyToVia() && replyToMsg->from()->isUser()) ? replyToMsg->from()->asUser()->firstName : App::peerName(replyToMsg->from());
|
||||||
|
replyToName.setText(st::msgServiceNameFont, name, _textNameOptions);
|
||||||
replyToVersion = replyToMsg->from()->nameVersion;
|
replyToVersion = replyToMsg->from()->nameVersion;
|
||||||
bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
|
bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
|
||||||
int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
|
int32 previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
|
||||||
|
int32 w = replyToName.maxWidth();
|
||||||
|
if (replyToVia()) {
|
||||||
|
w += st::msgServiceFont->spacew + replyToVia()->maxWidth;
|
||||||
|
}
|
||||||
|
|
||||||
_maxReplyWidth = previewSkip + qMax(replyToName.maxWidth(), qMin(replyToText.maxWidth(), 4 * replyToName.maxWidth()));
|
_maxReplyWidth = previewSkip + qMax(w, qMin(replyToText.maxWidth(), 4 * w));
|
||||||
} else {
|
} else {
|
||||||
_maxReplyWidth = st::msgDateFont->width(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message));
|
_maxReplyWidth = st::msgDateFont->width(lang(replyToMsgId ? lng_profile_loading : lng_deleted_message));
|
||||||
}
|
}
|
||||||
|
@ -7056,6 +7139,10 @@ void HistoryReply::drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selec
|
||||||
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
|
p.setPen(selected ? (outbg ? st::msgOutServiceFgSelected : st::msgInServiceFgSelected) : (outbg ? st::msgOutServiceFg : st::msgInServiceFg));
|
||||||
}
|
}
|
||||||
replyToName.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x);
|
replyToName.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top(), w - st::msgReplyBarSkip - previewSkip, w + 2 * x);
|
||||||
|
if (replyToVia() && w > st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew) {
|
||||||
|
p.setFont(st::msgServiceFont);
|
||||||
|
p.drawText(x + st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew, y + st::msgReplyPadding.top() + st::msgServiceFont->ascent, replyToVia()->text);
|
||||||
|
}
|
||||||
|
|
||||||
HistoryMessage *replyToAsMsg = replyToMsg->toHistoryMessage();
|
HistoryMessage *replyToAsMsg = replyToMsg->toHistoryMessage();
|
||||||
if (likeService) {
|
if (likeService) {
|
||||||
|
@ -7094,10 +7181,23 @@ int32 HistoryReply::resize(int32 width) {
|
||||||
} else {
|
} else {
|
||||||
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
_height += st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
|
||||||
}
|
}
|
||||||
|
if (replyToVia()) {
|
||||||
|
bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
|
||||||
|
int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
|
||||||
|
replyToVia()->resize(width - st::msgPadding.left() - st::msgPadding.right() - st::msgReplyBarSkip + previewSkip + replyToName.maxWidth() + st::msgServiceFont->spacew);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryReply::resizeVia(int32 w) const {
|
||||||
|
if (!replyToVia()) return;
|
||||||
|
|
||||||
|
bool hasPreview = replyToMsg->getMedia() ? replyToMsg->getMedia()->hasReplyPreview() : false;
|
||||||
|
int previewSkip = hasPreview ? (st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x()) : 0;
|
||||||
|
replyToVia()->resize(w - st::msgReplyBarSkip - previewSkip - replyToName.maxWidth() - st::msgServiceFont->spacew);
|
||||||
|
}
|
||||||
|
|
||||||
bool HistoryReply::hasPoint(int32 x, int32 y) const {
|
bool HistoryReply::hasPoint(int32 x, int32 y) const {
|
||||||
if (drawBubble()) {
|
if (drawBubble()) {
|
||||||
int32 left = 0, width = 0;
|
int32 left = 0, width = 0;
|
||||||
|
@ -7186,6 +7286,7 @@ HistoryReply::~HistoryReply() {
|
||||||
} else if (replyToMsgId && App::api()) {
|
} else if (replyToMsgId && App::api()) {
|
||||||
App::api()->itemRemoved(this);
|
App::api()->itemRemoved(this);
|
||||||
}
|
}
|
||||||
|
deleteAndMark(_replyToVia);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
void HistoryServiceMsg::setMessageByAction(const MTPmessageAction &action) {
|
||||||
|
|
|
@ -1680,6 +1680,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void initDimensions(const HistoryItem *parent);
|
void initDimensions(const HistoryItem *parent);
|
||||||
|
int32 resize(int32 width, const HistoryItem *parent);
|
||||||
|
|
||||||
void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const;
|
void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const;
|
||||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const;
|
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const;
|
||||||
|
@ -1979,7 +1980,7 @@ public:
|
||||||
|
|
||||||
UserData *bot;
|
UserData *bot;
|
||||||
QString text;
|
QString text;
|
||||||
int32 width, fullWidth;
|
int32 width, maxWidth;
|
||||||
TextLinkPtr lnk;
|
TextLinkPtr lnk;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -2164,7 +2165,7 @@ public:
|
||||||
}
|
}
|
||||||
QString selectedText(uint32 selection) const;
|
QString selectedText(uint32 selection) const;
|
||||||
bool displayForwardedFrom() const {
|
bool displayForwardedFrom() const {
|
||||||
return (!_media || !_media->isDisplayed() || !_media->hideForwardedFrom());
|
return via() || !_media || !_media->isDisplayed() || !_media->hideForwardedFrom();
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryForwarded *toHistoryForwarded() {
|
HistoryForwarded *toHistoryForwarded() {
|
||||||
|
@ -2207,6 +2208,7 @@ public:
|
||||||
void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
|
void drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selected, bool likeService = false) const;
|
||||||
void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
|
void drawMessageText(Painter &p, QRect trect, uint32 selection) const;
|
||||||
int32 resize(int32 width);
|
int32 resize(int32 width);
|
||||||
|
void resizeVia(int32 w) const;
|
||||||
bool hasPoint(int32 x, int32 y) const;
|
bool hasPoint(int32 x, int32 y) const;
|
||||||
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y) const;
|
||||||
void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const;
|
void getStateFromMessageText(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const QRect &r) const;
|
||||||
|
@ -2234,6 +2236,10 @@ protected:
|
||||||
mutable Text replyToName, replyToText;
|
mutable Text replyToName, replyToText;
|
||||||
mutable int32 replyToVersion;
|
mutable int32 replyToVersion;
|
||||||
mutable int32 _maxReplyWidth;
|
mutable int32 _maxReplyWidth;
|
||||||
|
HistoryMessageVia *_replyToVia;
|
||||||
|
HistoryMessageVia *replyToVia() const {
|
||||||
|
return (_replyToVia && !_replyToVia->isNull()) ? _replyToVia : 0;
|
||||||
|
}
|
||||||
int32 toWidth;
|
int32 toWidth;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -2630,6 +2630,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _migrated(0)
|
, _migrated(0)
|
||||||
, _history(0)
|
, _history(0)
|
||||||
, _histInited(false)
|
, _histInited(false)
|
||||||
|
, _lastScroll(0)
|
||||||
|
, _lastScrolled(0)
|
||||||
, _toHistoryEnd(this, st::historyToEnd)
|
, _toHistoryEnd(this, st::historyToEnd)
|
||||||
, _collapseComments(this)
|
, _collapseComments(this)
|
||||||
, _attachMention(this)
|
, _attachMention(this)
|
||||||
|
@ -2722,6 +2724,9 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
connect(audioCapture(), SIGNAL(onDone(QByteArray,qint32)), this, SLOT(onRecordDone(QByteArray,qint32)));
|
connect(audioCapture(), SIGNAL(onDone(QByteArray,qint32)), this, SLOT(onRecordDone(QByteArray,qint32)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updateHistoryItems.setSingleShot(true);
|
||||||
|
connect(&_updateHistoryItems, SIGNAL(timeout()), this, SLOT(onUpdateHistoryItems()));
|
||||||
|
|
||||||
_scrollTimer.setSingleShot(false);
|
_scrollTimer.setSingleShot(false);
|
||||||
|
|
||||||
_sendActionStopTimer.setSingleShot(true);
|
_sendActionStopTimer.setSingleShot(true);
|
||||||
|
@ -3508,6 +3513,8 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
_scroll.setWidget(_list);
|
_scroll.setWidget(_list);
|
||||||
_list->show();
|
_list->show();
|
||||||
|
|
||||||
|
_updateHistoryItems.stop();
|
||||||
|
|
||||||
if (_history->lastWidth || _history->isReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop)) {
|
if (_history->lastWidth || _history->isReadyFor(_showAtMsgId, _fixedInScrollMsgId, _fixedInScrollMsgTop)) {
|
||||||
_fixedInScrollMsgId = 0;
|
_fixedInScrollMsgId = 0;
|
||||||
_fixedInScrollMsgTop = 0;
|
_fixedInScrollMsgTop = 0;
|
||||||
|
@ -4360,6 +4367,11 @@ void HistoryWidget::onListScroll() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (st != _lastScroll) {
|
||||||
|
_lastScrolled = getms();
|
||||||
|
_lastScroll = st;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::onVisibleChanged() {
|
void HistoryWidget::onVisibleChanged() {
|
||||||
|
@ -4407,8 +4419,9 @@ void HistoryWidget::onSend(bool ctrlShiftEnter, MsgId replyTo) {
|
||||||
_saveDraftStart = getms();
|
_saveDraftStart = getms();
|
||||||
onDraftSave();
|
onDraftSave();
|
||||||
|
|
||||||
onCheckMentionDropdown();
|
if (!_attachMention.isHidden()) _attachMention.hideStart();
|
||||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||||
|
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||||
|
|
||||||
if (replyTo < 0) cancelReply(lastKeyboardUsed);
|
if (replyTo < 0) cancelReply(lastKeyboardUsed);
|
||||||
if (_previewData && _previewData->pendingTill) previewCancel();
|
if (_previewData && _previewData->pendingTill) previewCancel();
|
||||||
|
@ -5834,7 +5847,23 @@ bool HistoryWidget::isItemVisible(HistoryItem *item) {
|
||||||
|
|
||||||
void HistoryWidget::ui_repaintHistoryItem(const HistoryItem *item) {
|
void HistoryWidget::ui_repaintHistoryItem(const HistoryItem *item) {
|
||||||
if (_peer && _list && (item->history() == _history || (_migrated && item->history() == _migrated))) {
|
if (_peer && _list && (item->history() == _history || (_migrated && item->history() == _migrated))) {
|
||||||
_list->repaintItem(item);
|
uint64 ms = getms();
|
||||||
|
if (_lastScrolled + 100 <= ms) {
|
||||||
|
_list->repaintItem(item);
|
||||||
|
} else {
|
||||||
|
_updateHistoryItems.start(_lastScrolled + 100 - ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::onUpdateHistoryItems() {
|
||||||
|
if (!_list) return;
|
||||||
|
|
||||||
|
uint64 ms = getms();
|
||||||
|
if (_lastScrolled + 100 <= ms) {
|
||||||
|
_list->update();
|
||||||
|
} else {
|
||||||
|
_updateHistoryItems.start(_lastScrolled + 100 - ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6459,8 +6488,9 @@ void HistoryWidget::onInlineResultSend(InlineResult *result, UserData *bot) {
|
||||||
Local::writeRecentHashtagsAndBots();
|
Local::writeRecentHashtagsAndBots();
|
||||||
}
|
}
|
||||||
|
|
||||||
onCheckMentionDropdown();
|
if (!_attachMention.isHidden()) _attachMention.hideStart();
|
||||||
if (!_attachType.isHidden()) _attachType.hideStart();
|
if (!_attachType.isHidden()) _attachType.hideStart();
|
||||||
|
if (!_emojiPan.isHidden()) _emojiPan.hideStart();
|
||||||
|
|
||||||
_field.setFocus();
|
_field.setFocus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -682,6 +682,8 @@ public slots:
|
||||||
void onRecordDone(QByteArray result, qint32 samples);
|
void onRecordDone(QByteArray result, qint32 samples);
|
||||||
void onRecordUpdate(qint16 level, qint32 samples);
|
void onRecordUpdate(qint16 level, qint32 samples);
|
||||||
|
|
||||||
|
void onUpdateHistoryItems();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
MsgId _replyToId;
|
MsgId _replyToId;
|
||||||
|
@ -771,6 +773,10 @@ private:
|
||||||
History *_migrated, *_history;
|
History *_migrated, *_history;
|
||||||
bool _histInited; // initial updateListSize() called
|
bool _histInited; // initial updateListSize() called
|
||||||
|
|
||||||
|
int32 _lastScroll;
|
||||||
|
uint64 _lastScrolled;
|
||||||
|
QTimer _updateHistoryItems; // gifs optimization
|
||||||
|
|
||||||
IconedButton _toHistoryEnd;
|
IconedButton _toHistoryEnd;
|
||||||
CollapseButton _collapseComments;
|
CollapseButton _collapseComments;
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,21 @@ style::color documentColor(int32 colorIndex) {
|
||||||
return colors[colorIndex & 3];
|
return colors[colorIndex & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
style::color documentDarkColor(int32 colorIndex) {
|
||||||
|
static style::color colors[] = { st::msgFileBlueDark, st::msgFileGreenDark, st::msgFileRedDark, st::msgFileYellowDark };
|
||||||
|
return colors[colorIndex & 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
style::color documentOverColor(int32 colorIndex) {
|
||||||
|
static style::color colors[] = { st::msgFileBlueOver, st::msgFileGreenOver, st::msgFileRedOver, st::msgFileYellowOver };
|
||||||
|
return colors[colorIndex & 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
style::color documentSelectedColor(int32 colorIndex) {
|
||||||
|
static style::color colors[] = { st::msgFileBlueSelected, st::msgFileGreenSelected, st::msgFileRedSelected, st::msgFileYellowSelected };
|
||||||
|
return colors[colorIndex & 3];
|
||||||
|
}
|
||||||
|
|
||||||
style::sprite documentCorner(int32 colorIndex) {
|
style::sprite documentCorner(int32 colorIndex) {
|
||||||
static style::sprite corners[] = { st::msgFileBlue, st::msgFileGreen, st::msgFileRed, st::msgFileYellow };
|
static style::sprite corners[] = { st::msgFileBlue, st::msgFileGreen, st::msgFileRed, st::msgFileYellow };
|
||||||
return corners[colorIndex & 3];
|
return corners[colorIndex & 3];
|
||||||
|
@ -285,14 +300,14 @@ LayoutOverviewDate::LayoutOverviewDate(const QDate &date, bool month)
|
||||||
|
|
||||||
void LayoutOverviewDate::initDimensions() {
|
void LayoutOverviewDate::initDimensions() {
|
||||||
_maxw = st::normalFont->width(_text);
|
_maxw = st::normalFont->width(_text);
|
||||||
_minh = st::linksDateMargin + st::normalFont->height + st::linksDateMargin + st::linksBorder;
|
_minh = st::linksDateMargin.top() + st::normalFont->height + st::linksDateMargin.bottom() + st::linksBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||||
if (clip.intersects(QRect(0, st::linksDateMargin, _width, st::normalFont->height))) {
|
if (clip.intersects(QRect(0, st::linksDateMargin.top(), _width, st::normalFont->height))) {
|
||||||
p.setPen(st::linksDateColor);
|
p.setPen(st::linksDateColor);
|
||||||
p.setFont(st::normalFont);
|
p.setFont(st::semiboldFont);
|
||||||
p.drawTextLeft(0, st::linksDateMargin, _width, _text);
|
p.drawTextLeft(0, st::linksDateMargin.top(), _width, _text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,12 +644,24 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
|
||||||
if (clip.intersects(rtlrect(nameleft, statustop, namewidth, st::normalFont->height, _width))) {
|
if (clip.intersects(rtlrect(nameleft, statustop, namewidth, st::normalFont->height, _width))) {
|
||||||
p.setFont(st::normalFont);
|
p.setFont(st::normalFont);
|
||||||
p.setPen(selected ? st::mediaInFgSelected : st::mediaInFg);
|
p.setPen(selected ? st::mediaInFgSelected : st::mediaInFg);
|
||||||
|
int32 unreadx = nameleft;
|
||||||
if (_statusSize == FileStatusSizeLoaded || _statusSize == FileStatusSizeReady) {
|
if (_statusSize == FileStatusSizeLoaded || _statusSize == FileStatusSizeReady) {
|
||||||
textstyleSet(&(selected ? st::mediaInStyleSelected : st::mediaInStyle));
|
textstyleSet(&(selected ? st::mediaInStyleSelected : st::mediaInStyle));
|
||||||
_details.drawLeftElided(p, nameleft, statustop, namewidth, _width);
|
_details.drawLeftElided(p, nameleft, statustop, namewidth, _width);
|
||||||
textstyleRestore();
|
textstyleRestore();
|
||||||
|
unreadx += _details.maxWidth();
|
||||||
} else {
|
} else {
|
||||||
p.drawTextLeft(nameleft, statustop, _width, _statusText);
|
int32 statusw = st::normalFont->width(_statusText);
|
||||||
|
p.drawTextLeft(nameleft, statustop, _width, _statusText, statusw);
|
||||||
|
unreadx += statusw;
|
||||||
|
}
|
||||||
|
if (_parent->isMediaUnread() && unreadx + st::mediaUnreadSkip + st::mediaUnreadSize <= _width) {
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(selected ? st::msgFileInBgSelected : st::msgFileInBg);
|
||||||
|
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||||
|
p.drawEllipse(rtlrect(unreadx + st::mediaUnreadSkip, statustop + st::mediaUnreadTop, st::mediaUnreadSize, st::mediaUnreadSize, _width));
|
||||||
|
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -715,6 +742,7 @@ LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryIt
|
||||||
, _data(document)
|
, _data(document)
|
||||||
, _msgl(new MessageLink(parent))
|
, _msgl(new MessageLink(parent))
|
||||||
, _namel(new DocumentOpenLink(_data))
|
, _namel(new DocumentOpenLink(_data))
|
||||||
|
, _thumbForLoaded(false)
|
||||||
, _name(documentName(_data))
|
, _name(documentName(_data))
|
||||||
, _date(langDateTime(date(_data->date)))
|
, _date(langDateTime(date(_data->date)))
|
||||||
, _namew(st::semiboldFont->width(_name))
|
, _namew(st::semiboldFont->width(_name))
|
||||||
|
@ -728,17 +756,17 @@ LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryIt
|
||||||
_data->thumb->load();
|
_data->thumb->load();
|
||||||
int32 tw = _data->thumb->width(), th = _data->thumb->height();
|
int32 tw = _data->thumb->width(), th = _data->thumb->height();
|
||||||
if (tw > th) {
|
if (tw > th) {
|
||||||
_thumbw = (tw * st::msgFileThumbSize) / th;
|
_thumbw = (tw * st::overviewFileSize) / th;
|
||||||
} else {
|
} else {
|
||||||
_thumbw = st::msgFileThumbSize;
|
_thumbw = st::overviewFileSize;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_thumbw = 0;
|
_thumbw = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
_extw = st::semiboldFont->width(_ext);
|
_extw = st::semiboldFont->width(_ext);
|
||||||
if (_extw > st::msgFileThumbSize - st::msgFileExtPadding * 2) {
|
if (_extw > st::overviewFileSize - st::msgFileExtPadding * 2) {
|
||||||
_ext = st::semiboldFont->elided(_ext, st::msgFileThumbSize - st::msgFileExtPadding * 2, Qt::ElideMiddle);
|
_ext = st::semiboldFont->elided(_ext, st::overviewFileSize - st::msgFileExtPadding * 2, Qt::ElideMiddle);
|
||||||
_extw = st::semiboldFont->width(_ext);
|
_extw = st::semiboldFont->width(_ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -748,7 +776,7 @@ void LayoutOverviewDocument::initDimensions() {
|
||||||
if (_data->song()) {
|
if (_data->song()) {
|
||||||
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
_minh = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
||||||
} else {
|
} else {
|
||||||
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() + st::lineWidth;
|
_minh = st::overviewFilePadding.top() + st::overviewFileSize + st::overviewFilePadding.bottom() + st::lineWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,39 +845,40 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
||||||
p.drawSpriteCenter(inner, icon);
|
p.drawSpriteCenter(inner, icon);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nameleft = st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
nameleft = st::overviewFileSize + st::overviewFilePadding.right();
|
||||||
nametop = st::linksBorder + st::msgFileThumbNameTop;
|
nametop = st::linksBorder + st::overviewFileNameTop;
|
||||||
statustop = st::linksBorder + st::msgFileThumbStatusTop;
|
statustop = st::linksBorder + st::overviewFileStatusTop;
|
||||||
datetop = st::linksBorder + st::msgFileThumbLinkTop;
|
datetop = st::linksBorder + st::overviewFileDateTop;
|
||||||
|
|
||||||
QRect shadow(rtlrect(nameleft, 0, _width - nameleft, st::linksBorder, _width));
|
const OverviewPaintContext *pcontext = context->toOverviewPaintContext();
|
||||||
if (clip.intersects(shadow)) {
|
t_assert(pcontext != 0);
|
||||||
p.fillRect(clip.intersected(shadow), st::linksBorderFg);
|
QRect border(rtlrect(nameleft, 0, _width - nameleft, st::linksBorder, _width));
|
||||||
|
if (!pcontext->isAfterDate && clip.intersects(border)) {
|
||||||
|
p.fillRect(clip.intersected(border), st::linksBorderFg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
|
QRect rthumb(rtlrect(0, st::linksBorder + st::overviewFilePadding.top(), st::overviewFileSize, st::overviewFileSize, _width));
|
||||||
if (clip.intersects(rthumb)) {
|
if (clip.intersects(rthumb)) {
|
||||||
if (wthumb) {
|
if (wthumb) {
|
||||||
if (_data->thumb->loaded()) {
|
if (_data->thumb->loaded()) {
|
||||||
QPixmap thumb = loaded ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
|
if (_thumb.isNull() || loaded != _thumbForLoaded) {
|
||||||
p.drawPixmap(rthumb.topLeft(), thumb);
|
_thumbForLoaded = loaded;
|
||||||
|
_thumb = _data->thumb->pixNoCache(_thumbw, 0, true, !_thumbForLoaded, false, st::overviewFileSize, st::overviewFileSize);
|
||||||
|
}
|
||||||
|
p.drawPixmap(rthumb.topLeft(), _thumb);
|
||||||
} else {
|
} else {
|
||||||
App::roundRect(p, rthumb, st::black, BlackCorners);
|
p.fillRect(rthumb, st::black);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
App::roundRect(p, rthumb, documentColor(_colorIndex), documentCorners(_colorIndex));
|
p.fillRect(rthumb, documentColor(_colorIndex));
|
||||||
if (!radial && loaded) {
|
if (!radial && loaded && !_ext.isEmpty()) {
|
||||||
style::sprite icon = documentCorner(_colorIndex);
|
p.setFont(st::semiboldFont);
|
||||||
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - icon.pxWidth()), 0), icon);
|
p.setPen(st::white);
|
||||||
if (!_ext.isEmpty()) {
|
p.drawText(rthumb.left() + (rthumb.width() - _extw) / 2, rthumb.top() + st::msgFileExtTop + st::semiboldFont->ascent, _ext);
|
||||||
p.setFont(st::semiboldFont);
|
|
||||||
p.setPen(st::white);
|
|
||||||
p.drawText(rthumb.left() + (rthumb.width() - _extw) / 2, rthumb.top() + st::msgFileExtTop + st::semiboldFont->ascent, _ext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
|
p.fillRect(rthumb, textstyleCurrent()->selectOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (radial || (!loaded && !_data->loading())) {
|
if (radial || (!loaded && !_data->loading())) {
|
||||||
|
@ -858,15 +887,19 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
||||||
float64 radialOpacity = (radial && loaded && !_data->uploading()) ? _radial->opacity() : 1;
|
float64 radialOpacity = (radial && loaded && !_data->uploading()) ? _radial->opacity() : 1;
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
if (selected) {
|
if (selected) {
|
||||||
p.setBrush(st::msgDateImgBgSelected);
|
p.setBrush(wthumb ? st::msgDateImgBgSelected : documentSelectedColor(_colorIndex));
|
||||||
} else if (_a_iconOver.animating()) {
|
} else if (_a_iconOver.animating()) {
|
||||||
_a_iconOver.step(context->ms);
|
_a_iconOver.step(context->ms);
|
||||||
float64 over = a_iconOver.current();
|
float64 over = a_iconOver.current();
|
||||||
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
|
if (wthumb) {
|
||||||
p.setBrush(st::black);
|
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
|
||||||
|
p.setBrush(st::black);
|
||||||
|
} else {
|
||||||
|
p.setBrush(style::interpolate(documentDarkColor(_colorIndex), documentOverColor(_colorIndex), over));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
bool over = textlnkDrawOver(_data->loading() ? _cancell : _savel);
|
bool over = textlnkDrawOver(_data->loading() ? _cancell : _savel);
|
||||||
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
|
p.setBrush(over ? (wthumb ? st::msgDateImgBgOver : documentOverColor(_colorIndex)) : (wthumb ? st::msgDateImgBg : documentDarkColor(_colorIndex)));
|
||||||
}
|
}
|
||||||
p.setOpacity(radialOpacity * p.opacity());
|
p.setOpacity(radialOpacity * p.opacity());
|
||||||
|
|
||||||
|
@ -890,10 +923,10 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected || context->selecting) {
|
||||||
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::linksPhotoChecked.pxWidth()), rthumb.height() - st::linksPhotoChecked.pxHeight()), st::linksPhotoChecked);
|
QRect check(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::defaultCheckbox.diameter), rthumb.height() - st::defaultCheckbox.diameter), QSize(st::defaultCheckbox.diameter, st::defaultCheckbox.diameter));
|
||||||
} else if (context->selecting) {
|
p.fillRect(check, selected ? st::overviewFileChecked : st::overviewFileCheck);
|
||||||
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::linksPhotoCheck.pxWidth()), rthumb.height() - st::linksPhotoCheck.pxHeight()), st::linksPhotoCheck);
|
p.drawSpriteCenter(check, st::defaultCheckbox.checkIcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -946,12 +979,12 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nameleft = st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
nameleft = st::overviewFileSize + st::overviewFilePadding.right();
|
||||||
nametop = st::linksBorder + st::msgFileThumbNameTop;
|
nametop = st::linksBorder + st::overviewFileNameTop;
|
||||||
statustop = st::linksBorder + st::msgFileThumbStatusTop;
|
statustop = st::linksBorder + st::overviewFileStatusTop;
|
||||||
datetop = st::linksBorder + st::msgFileThumbLinkTop;
|
datetop = st::linksBorder + st::overviewFileDateTop;
|
||||||
|
|
||||||
QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
|
QRect rthumb(rtlrect(0, st::linksBorder + st::overviewFilePadding.top(), st::overviewFileSize, st::overviewFileSize, _width));
|
||||||
|
|
||||||
if (rthumb.contains(x, y)) {
|
if (rthumb.contains(x, y)) {
|
||||||
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel);
|
link = loaded ? _openl : ((_data->loading() || _data->status == FileUploading) ? _cancell : _savel);
|
||||||
|
@ -1150,7 +1183,7 @@ void LayoutOverviewLink::initDimensions() {
|
||||||
_minh += qMin(3 * st::normalFont->height, _text.countHeight(_maxw - st::dlgPhotoSize - st::dlgPhotoPadding));
|
_minh += qMin(3 * st::normalFont->height, _text.countHeight(_maxw - st::dlgPhotoSize - st::dlgPhotoPadding));
|
||||||
}
|
}
|
||||||
_minh += _links.size() * st::normalFont->height;
|
_minh += _links.size() * st::normalFont->height;
|
||||||
_minh = qMax(_minh, int32(st::dlgPhotoSize)) + st::linksMargin * 2 + st::linksBorder;
|
_minh = qMax(_minh, int32(st::dlgPhotoSize)) + st::linksMargin.top() + st::linksMargin.bottom() + st::linksBorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 LayoutOverviewLink::resizeGetHeight(int32 width) {
|
int32 LayoutOverviewLink::resizeGetHeight(int32 width) {
|
||||||
|
@ -1168,12 +1201,12 @@ int32 LayoutOverviewLink::resizeGetHeight(int32 width) {
|
||||||
_height += qMin(3 * st::normalFont->height, _text.countHeight(_width - st::dlgPhotoSize - st::dlgPhotoPadding));
|
_height += qMin(3 * st::normalFont->height, _text.countHeight(_width - st::dlgPhotoSize - st::dlgPhotoPadding));
|
||||||
}
|
}
|
||||||
_height += _links.size() * st::normalFont->height;
|
_height += _links.size() * st::normalFont->height;
|
||||||
_height = qMax(_height, int32(st::dlgPhotoSize)) + st::linksMargin * 2 + st::linksBorder;
|
_height = qMax(_height, int32(st::dlgPhotoSize)) + st::linksMargin.top() + st::linksMargin.bottom() + st::linksBorder;
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewLink::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
void LayoutOverviewLink::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
|
||||||
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin + st::linksBorder, w = _width - left;
|
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
||||||
if (clip.intersects(rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width))) {
|
if (clip.intersects(rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width))) {
|
||||||
if (_page && _page->photo) {
|
if (_page && _page->photo) {
|
||||||
QPixmap pix;
|
QPixmap pix;
|
||||||
|
@ -1213,6 +1246,8 @@ void LayoutOverviewLink::paint(Painter &p, const QRect &clip, uint32 selection,
|
||||||
|
|
||||||
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
|
if (!_title.isEmpty() && _text.isEmpty() && _links.size() == 1) {
|
||||||
top += (st::dlgPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
|
top += (st::dlgPhotoSize - st::semiboldFont->height - st::normalFont->height) / 2;
|
||||||
|
} else {
|
||||||
|
top = st::linksTextTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen(st::black);
|
p.setPen(st::black);
|
||||||
|
@ -1241,13 +1276,16 @@ void LayoutOverviewLink::paint(Painter &p, const QRect &clip, uint32 selection,
|
||||||
top += st::normalFont->height;
|
top += st::normalFont->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clip.intersects(rtlrect(left, 0, w, st::linksBorder, _width))) {
|
const OverviewPaintContext *pcontext = context->toOverviewPaintContext();
|
||||||
p.fillRect(clip.intersected(rtlrect(left, 0, w, st::linksBorder, _width)), st::linksBorderFg);
|
t_assert(pcontext != 0);
|
||||||
|
QRect border(rtlrect(left, 0, w, st::linksBorder, _width));
|
||||||
|
if (!pcontext->isAfterDate && clip.intersects(border)) {
|
||||||
|
p.fillRect(clip.intersected(border), st::linksBorderFg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutOverviewLink::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
void LayoutOverviewLink::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||||
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin + st::linksBorder, w = _width - left;
|
int32 left = st::dlgPhotoSize + st::dlgPhotoPadding, top = st::linksMargin.top() + st::linksBorder, w = _width - left;
|
||||||
if (rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width).contains(x, y)) {
|
if (rtlrect(0, top, st::dlgPhotoSize, st::dlgPhotoSize, _width).contains(x, y)) {
|
||||||
link = _photol;
|
link = _photol;
|
||||||
return;
|
return;
|
||||||
|
@ -1809,6 +1847,7 @@ void LayoutInlinePhoto::content_forget() {
|
||||||
|
|
||||||
LayoutInlineWebVideo::LayoutInlineWebVideo(InlineResult *result) : LayoutInlineItem(result, 0, 0)
|
LayoutInlineWebVideo::LayoutInlineWebVideo(InlineResult *result) : LayoutInlineItem(result, 0, 0)
|
||||||
, _send(new SendInlineItemLink())
|
, _send(new SendInlineItemLink())
|
||||||
|
, _link(result->content_url.isEmpty() ? 0 : linkFromUrl(result->content_url))
|
||||||
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
||||||
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||||
if (_result->duration) {
|
if (_result->duration) {
|
||||||
|
@ -1866,8 +1905,13 @@ void LayoutInlineWebVideo::paint(Painter &p, const QRect &clip, uint32 selection
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutInlineWebVideo::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
void LayoutInlineWebVideo::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||||
if (x >= 0 && x < _width && y >= 0 && y < _height) {
|
if (x >= 0 && x < st::inlineThumbSize && y >= st::inlineRowMargin && y < st::inlineRowMargin + st::inlineThumbSize) {
|
||||||
|
link = _link;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x >= st::inlineThumbSize + st::inlineThumbSkip && x < _width && y >= 0 && y < _height) {
|
||||||
link = _send;
|
link = _send;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1896,6 +1940,7 @@ void LayoutInlineWebVideo::prepareThumb(int32 width, int32 height) const {
|
||||||
LayoutInlineArticle::LayoutInlineArticle(InlineResult *result, bool withThumb) : LayoutInlineItem(result, 0, 0)
|
LayoutInlineArticle::LayoutInlineArticle(InlineResult *result, bool withThumb) : LayoutInlineItem(result, 0, 0)
|
||||||
, _send(new SendInlineItemLink())
|
, _send(new SendInlineItemLink())
|
||||||
, _url(result->url.isEmpty() ? 0 : linkFromUrl(result->url))
|
, _url(result->url.isEmpty() ? 0 : linkFromUrl(result->url))
|
||||||
|
, _link(result->content_url.isEmpty() ? 0 : linkFromUrl(result->content_url))
|
||||||
, _withThumb(withThumb)
|
, _withThumb(withThumb)
|
||||||
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
|
||||||
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
|
||||||
|
@ -1995,7 +2040,12 @@ void LayoutInlineArticle::paint(Painter &p, const QRect &clip, uint32 selection,
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayoutInlineArticle::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
void LayoutInlineArticle::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
|
||||||
if (x >= 0 && x < _width && y >= 0 && y < _height) {
|
int32 left = _withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0;
|
||||||
|
if (x >= 0 && x < left - st::inlineThumbSkip && y >= st::inlineRowMargin && y < st::inlineRowMargin + st::inlineThumbSize) {
|
||||||
|
link = _link;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x >= left && x < _width && y >= 0 && y < _height) {
|
||||||
if (_url) {
|
if (_url) {
|
||||||
int32 left = st::inlineThumbSize + st::inlineThumbSkip;
|
int32 left = st::inlineThumbSize + st::inlineThumbSkip;
|
||||||
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
|
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
|
||||||
|
@ -2007,6 +2057,7 @@ void LayoutInlineArticle::getState(TextLinkPtr &link, HistoryCursorState &cursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
link = _send;
|
link = _send;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,9 +75,13 @@ QString formatPlayedText(qint64 played, qint64 duration);
|
||||||
QString documentName(DocumentData *document);
|
QString documentName(DocumentData *document);
|
||||||
int32 documentColorIndex(DocumentData *document, QString &ext);
|
int32 documentColorIndex(DocumentData *document, QString &ext);
|
||||||
style::color documentColor(int32 colorIndex);
|
style::color documentColor(int32 colorIndex);
|
||||||
|
style::color documentDarkColor(int32 colorIndex);
|
||||||
|
style::color documentOverColor(int32 colorIndex);
|
||||||
|
style::color documentSelectedColor(int32 colorIndex);
|
||||||
style::sprite documentCorner(int32 colorIndex);
|
style::sprite documentCorner(int32 colorIndex);
|
||||||
RoundCorners documentCorners(int32 colorIndex);
|
RoundCorners documentCorners(int32 colorIndex);
|
||||||
|
|
||||||
|
class OverviewPaintContext;
|
||||||
class InlinePaintContext;
|
class InlinePaintContext;
|
||||||
class PaintContext {
|
class PaintContext {
|
||||||
public:
|
public:
|
||||||
|
@ -86,6 +90,10 @@ public:
|
||||||
}
|
}
|
||||||
uint64 ms;
|
uint64 ms;
|
||||||
bool selecting;
|
bool selecting;
|
||||||
|
|
||||||
|
virtual const OverviewPaintContext *toOverviewPaintContext() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
virtual const InlinePaintContext *toInlinePaintContext() const {
|
virtual const InlinePaintContext *toInlinePaintContext() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -257,6 +265,17 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class OverviewPaintContext : public PaintContext {
|
||||||
|
public:
|
||||||
|
OverviewPaintContext(uint64 ms, bool selecting) : PaintContext(ms, selecting), isAfterDate(false) {
|
||||||
|
}
|
||||||
|
const OverviewPaintContext *toOverviewPaintContext() const {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
bool isAfterDate;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class OverviewItemInfo {
|
class OverviewItemInfo {
|
||||||
public:
|
public:
|
||||||
OverviewItemInfo() : _top(0) {
|
OverviewItemInfo() : _top(0) {
|
||||||
|
@ -267,7 +286,7 @@ public:
|
||||||
void setTop(int32 top) {
|
void setTop(int32 top) {
|
||||||
_top = top;
|
_top = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32 _top;
|
int32 _top;
|
||||||
|
|
||||||
|
@ -276,7 +295,7 @@ private:
|
||||||
class LayoutOverviewDate : public LayoutItem {
|
class LayoutOverviewDate : public LayoutItem {
|
||||||
public:
|
public:
|
||||||
LayoutOverviewDate(const QDate &date, bool month);
|
LayoutOverviewDate(const QDate &date, bool month);
|
||||||
|
|
||||||
virtual void initDimensions();
|
virtual void initDimensions();
|
||||||
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
virtual void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const;
|
||||||
|
|
||||||
|
@ -426,6 +445,9 @@ private:
|
||||||
DocumentData *_data;
|
DocumentData *_data;
|
||||||
TextLinkPtr _msgl, _namel;
|
TextLinkPtr _msgl, _namel;
|
||||||
|
|
||||||
|
mutable bool _thumbForLoaded;
|
||||||
|
mutable QPixmap _thumb;
|
||||||
|
|
||||||
QString _name, _date, _ext;
|
QString _name, _date, _ext;
|
||||||
int32 _namew, _datew, _extw;
|
int32 _namew, _datew, _extw;
|
||||||
int32 _thumbw, _colorIndex;
|
int32 _thumbw, _colorIndex;
|
||||||
|
@ -492,7 +514,7 @@ class LayoutInlineItem : public LayoutItem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LayoutInlineItem(InlineResult *result, DocumentData *doc, PhotoData *photo);
|
LayoutInlineItem(InlineResult *result, DocumentData *doc, PhotoData *photo);
|
||||||
|
|
||||||
virtual void setPosition(int32 position);
|
virtual void setPosition(int32 position);
|
||||||
int32 position() const;
|
int32 position() const;
|
||||||
|
|
||||||
|
@ -644,7 +666,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TextLinkPtr _send;
|
TextLinkPtr _send, _link;
|
||||||
|
|
||||||
mutable QPixmap _thumb;
|
mutable QPixmap _thumb;
|
||||||
Text _title, _description;
|
Text _title, _description;
|
||||||
|
@ -667,7 +689,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
TextLinkPtr _send, _url;
|
TextLinkPtr _send, _url, _link;
|
||||||
|
|
||||||
bool _withThumb;
|
bool _withThumb;
|
||||||
mutable QPixmap _thumb;
|
mutable QPixmap _thumb;
|
||||||
|
|
|
@ -834,7 +834,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
}
|
}
|
||||||
uint64 ms = getms();
|
uint64 ms = getms();
|
||||||
PaintContext context(ms, _selMode);
|
OverviewPaintContext context(ms, _selMode);
|
||||||
|
|
||||||
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
|
if (_history->overview[_type].isEmpty() && (!_migrated || !_history->overviewLoaded(_type) || _migrated->overview[_type].isEmpty())) {
|
||||||
QPoint dogPos((_width - st::msgDogImg.pxWidth()) / 2, ((height() - st::msgDogImg.pxHeight()) * 4) / 9);
|
QPoint dogPos((_width - st::msgDogImg.pxWidth()) / 2, ((height() - st::msgDogImg.pxHeight()) * 4) / 9);
|
||||||
|
@ -887,6 +887,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) {
|
||||||
if (_reversed) curY = _height - curY;
|
if (_reversed) curY = _height - curY;
|
||||||
if (_marginTop + curY >= r.y() + r.height()) break;
|
if (_marginTop + curY >= r.y() + r.height()) break;
|
||||||
|
|
||||||
|
context.isAfterDate = (j > 0) ? !_items.at(j - 1)->toLayoutMediaItem() : false;
|
||||||
p.translate(0, curY - y);
|
p.translate(0, curY - y);
|
||||||
_items.at(i)->paint(p, r.translated(-_rowsLeft, -_marginTop - curY), itemSelectedValue(i), &context);
|
_items.at(i)->paint(p, r.translated(-_rowsLeft, -_marginTop - curY), itemSelectedValue(i), &context);
|
||||||
y = curY;
|
y = curY;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.9.15</string>
|
<string>0.9.16</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
|
|
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,9,15,7
|
FILEVERSION 0,9,16,0
|
||||||
PRODUCTVERSION 0,9,15,7
|
PRODUCTVERSION 0,9,16,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -51,10 +51,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.9.15.7"
|
VALUE "FileVersion", "0.9.16.0"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2013"
|
VALUE "LegalCopyright", "Copyright (C) 2013"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.9.15.7"
|
VALUE "ProductVersion", "0.9.16.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -1701,7 +1701,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.9.15;
|
CURRENT_PROJECT_VERSION = 0.9.16;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
GCC_OPTIMIZATION_LEVEL = 0;
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
@ -1720,7 +1720,7 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
COPY_PHASE_STRIP = YES;
|
COPY_PHASE_STRIP = YES;
|
||||||
CURRENT_PROJECT_VERSION = 0.9.15;
|
CURRENT_PROJECT_VERSION = 0.9.16;
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
|
||||||
GCC_OPTIMIZATION_LEVEL = fast;
|
GCC_OPTIMIZATION_LEVEL = fast;
|
||||||
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
GCC_PREFIX_HEADER = ./SourceFiles/stdafx.h;
|
||||||
|
@ -1747,10 +1747,10 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.9.15;
|
CURRENT_PROJECT_VERSION = 0.9.16;
|
||||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
DYLIB_COMPATIBILITY_VERSION = 0.9;
|
DYLIB_COMPATIBILITY_VERSION = 0.9;
|
||||||
DYLIB_CURRENT_VERSION = 0.9.15;
|
DYLIB_CURRENT_VERSION = 0.9.16;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = "";
|
FRAMEWORK_SEARCH_PATHS = "";
|
||||||
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
|
||||||
|
@ -1882,10 +1882,10 @@
|
||||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
CODE_SIGN_IDENTITY = "";
|
CODE_SIGN_IDENTITY = "";
|
||||||
COPY_PHASE_STRIP = NO;
|
COPY_PHASE_STRIP = NO;
|
||||||
CURRENT_PROJECT_VERSION = 0.9.15;
|
CURRENT_PROJECT_VERSION = 0.9.16;
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
DYLIB_COMPATIBILITY_VERSION = 0.9;
|
DYLIB_COMPATIBILITY_VERSION = 0.9;
|
||||||
DYLIB_CURRENT_VERSION = 0.9.15;
|
DYLIB_CURRENT_VERSION = 0.9.16;
|
||||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
ENABLE_TESTABILITY = YES;
|
ENABLE_TESTABILITY = YES;
|
||||||
FRAMEWORK_SEARCH_PATHS = "";
|
FRAMEWORK_SEARCH_PATHS = "";
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
AppVersion 9015
|
AppVersion 9016
|
||||||
AppVersionStrMajor 0.9
|
AppVersionStrMajor 0.9
|
||||||
AppVersionStrSmall 0.9.15
|
AppVersionStrSmall 0.9.16
|
||||||
AppVersionStr 0.9.15
|
AppVersionStr 0.9.16
|
||||||
DevChannel 0
|
DevChannel 0
|
||||||
BetaVersion 9015007
|
BetaVersion 0 9015008
|
||||||
|
|
Loading…
Reference in New Issue