From 5f12c6d85b45900997303b5d70414e331ebc25da Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 10 Apr 2016 15:13:37 +0400 Subject: [PATCH] Always create photo and document for inline bot results. --- Telegram/SourceFiles/boxes/connectionbox.cpp | 1 - Telegram/SourceFiles/dropdown.cpp | 8 - Telegram/SourceFiles/dropdown.h | 1 - Telegram/SourceFiles/facades.cpp | 4 - Telegram/SourceFiles/facades.h | 2 - Telegram/SourceFiles/historywidget.cpp | 4 - Telegram/SourceFiles/historywidget.h | 1 - .../inline_bot_layout_internal.cpp | 222 ++++---------- .../inline_bots/inline_bot_layout_internal.h | 13 - .../inline_bots/inline_bot_layout_item.cpp | 12 - .../inline_bots/inline_bot_layout_item.h | 3 - .../inline_bots/inline_bot_result.cpp | 280 ++++++------------ .../inline_bots/inline_bot_result.h | 15 +- .../inline_bots/inline_bot_send_data.cpp | 105 +------ .../inline_bots/inline_bot_send_data.h | 25 +- Telegram/SourceFiles/mainwidget.cpp | 4 - Telegram/SourceFiles/mainwidget.h | 1 - Telegram/SourceFiles/structs.h | 5 +- Telegram/SourceFiles/ui/images.cpp | 150 +++++----- Telegram/SourceFiles/ui/images.h | 61 ++-- 20 files changed, 275 insertions(+), 642 deletions(-) diff --git a/Telegram/SourceFiles/boxes/connectionbox.cpp b/Telegram/SourceFiles/boxes/connectionbox.cpp index aa5ebd767..c9d65c3bb 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.cpp +++ b/Telegram/SourceFiles/boxes/connectionbox.cpp @@ -336,7 +336,6 @@ void AutoDownloadBox::onSave() { i.value()->automaticLoadSettingsChanged(); } } - Notify::automaticLoadSettingsChangedGif(); } changed = true; } diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 6682ac4ee..c24fbedc5 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -3412,14 +3412,6 @@ bool EmojiPan::ui_isInlineItemBeingChosen() { return false; } -void EmojiPan::notify_automaticLoadSettingsChangedGif() { - for_const (const internal::InlineCacheEntry *entry, _inlineCache) { - for_const (InlineBots::Result *l, entry->results) { - l->automaticLoadSettingsChangedGif(); - } - } -} - void EmojiPan::showAll() { if (_stickersShown) { s_scroll.show(); diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h index cc7e9b452..492d04760 100644 --- a/Telegram/SourceFiles/dropdown.h +++ b/Telegram/SourceFiles/dropdown.h @@ -614,7 +614,6 @@ public: bool inlineResultsShown() const { return s_inner.inlineResultsShown(); } - void notify_automaticLoadSettingsChangedGif(); public slots: diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 2dc0cf2c1..c50d34a2c 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -292,10 +292,6 @@ namespace Notify { if (MainWidget *m = App::main()) m->notify_historyItemLayoutChanged(item); } - void automaticLoadSettingsChangedGif() { - if (MainWidget *m = App::main()) m->notify_automaticLoadSettingsChangedGif(); - } - void handlePendingHistoryUpdate() { if (MainWidget *m = App::main()) { m->notify_handlePendingHistoryUpdate(); diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 862652c9b..a8e3631e9 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -111,8 +111,6 @@ namespace Notify { void historyItemLayoutChanged(const HistoryItem *item); - void automaticLoadSettingsChangedGif(); - // handle pending resize() / paint() on history items void handlePendingHistoryUpdate(); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 3a2870a5a..1750dafc4 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -6394,10 +6394,6 @@ void HistoryWidget::notify_historyItemLayoutChanged(const HistoryItem *item) { } } -void HistoryWidget::notify_automaticLoadSettingsChangedGif() { - _emojiPan.notify_automaticLoadSettingsChangedGif(); -} - void HistoryWidget::notify_handlePendingHistoryUpdate() { if (hasPendingResizedItems()) { updateListSize(); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 1544d2b12..beca58658 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -688,7 +688,6 @@ public: void notify_userIsBotChanged(UserData *user); void notify_migrateUpdated(PeerData *peer); void notify_clipStopperHidden(ClipStopperType type); - void notify_automaticLoadSettingsChangedGif(); void notify_handlePendingHistoryUpdate(); void cmd_search(); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp index d0ed5b1a4..39c314b9a 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.cpp @@ -44,107 +44,37 @@ DocumentData *FileBase::getShownDocument() const { } int FileBase::content_width() const { - if (DocumentData *document = getShownDocument()) { - if (document->dimensions.width() > 0) { - return document->dimensions.width(); - } - if (!document->thumb->isNull()) { - return convertScale(document->thumb->width()); - } + DocumentData *document = getShownDocument(); + if (document->dimensions.width() > 0) { + return document->dimensions.width(); } - return getResultWidth(); + if (!document->thumb->isNull()) { + return convertScale(document->thumb->width()); + } + return 0; } int FileBase::content_height() const { - if (DocumentData *document = getShownDocument()) { - if (document->dimensions.height() > 0) { - return document->dimensions.height(); - } - if (!document->thumb->isNull()) { - return convertScale(document->thumb->height()); - } + DocumentData *document = getShownDocument(); + if (document->dimensions.height() > 0) { + return document->dimensions.height(); } - return getResultHeight(); -} - -bool FileBase::content_loading() const { - if (DocumentData *document = getShownDocument()) { - return document->loading(); + if (!document->thumb->isNull()) { + return convertScale(document->thumb->height()); } - return _result->loading(); -} - -bool FileBase::content_displayLoading() const { - if (DocumentData *document = getShownDocument()) { - return document->displayLoading(); - } - return _result->displayLoading(); -} - -bool FileBase::content_loaded() const { - if (DocumentData *document = getShownDocument()) { - return document->loaded(); - } - return _result->loaded(); -} - -float64 FileBase::content_progress() const { - if (DocumentData *document = getShownDocument()) { - return document->progress(); - } - return _result->progress(); -} - -void FileBase::content_automaticLoad() const { - if (DocumentData *document = getShownDocument()) { - document->automaticLoad(nullptr); - } else { - _result->automaticLoadGif(); - } -} - -void FileBase::content_forget() { - if (DocumentData *document = getShownDocument()) { - document->forget(); - } else { - _result->forget(); - } -} - -FileLocation FileBase::content_location() const { - if (DocumentData *document = getShownDocument()) { - return document->location(); - } - return FileLocation(); -} - -QByteArray FileBase::content_data() const { - if (DocumentData *document = getShownDocument()) { - return document->data(); - } - return _result->data(); -} - -ImagePtr FileBase::content_thumb() const { - if (DocumentData *document = getShownDocument()) { - if (!document->thumb->isNull()) { - return document->thumb; - } - } - return getResultThumb(); + return 0; } int FileBase::content_duration() const { - if (DocumentData *document = getShownDocument()) { - if (document->duration() > 0) { - return document->duration(); - } else if (SongData *song = document->song()) { - if (song->duration) { - return song->duration; - } + DocumentData *document = getShownDocument(); + if (document->duration() > 0) { + return document->duration(); + } else if (SongData *song = document->song()) { + if (song->duration) { + return song->duration; } } - return getResultDuration(); + return 0; } Gif::Gif(Result *result) : FileBase(result) { @@ -185,12 +115,13 @@ void DeleteSavedGifClickHandler::onClickImpl() const { } void Gif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { - content_automaticLoad(); + DocumentData *document = getShownDocument(); + document->automaticLoad(nullptr); - bool loaded = content_loaded(), loading = content_loading(), displayLoading = content_displayLoading(); + bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading(); if (loaded && !gif() && _gif != BadClipReader) { Gif *that = const_cast(this); - that->_gif = new ClipReader(content_location(), content_data(), func(that, &Gif::clipCallback)); + that->_gif = new ClipReader(document->location(), document->data(), func(that, &Gif::clipCallback)); if (gif()) _gif->setAutoplay(); } @@ -198,7 +129,7 @@ void Gif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCont if (displayLoading) { ensureAnimation(); if (!_animation->radial.animating()) { - _animation->radial.start(content_progress()); + _animation->radial.start(document->progress()); } } bool radial = isRadialAnimation(context->ms); @@ -255,6 +186,9 @@ void Gif::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCont p.drawSpriteLeft(deletePos, _width, st::stickerPanDelete); p.setOpacity(1); } + if (!document->hasRemoteLocation()) { + p.fillRect(10, 10, 30, 30, QColor(255, 0, 0)); + } } void Gif::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { @@ -286,7 +220,7 @@ void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { if (p == _delete || p == _send) { bool wasactive = (_state & StateFlag::Over); if (active != wasactive) { - if (!content_loaded()) { + if (!getShownDocument()->loaded()) { ensureAnimation(); float64 from = active ? 0 : 1, to = active ? 1 : 0; EnsureAnimation(_animation->_a_over, from, func(this, &Gif::update)); @@ -376,10 +310,11 @@ void Gif::step_radial(uint64 ms, bool timer) { if (timer) { update(); } else { - _animation->radial.update(content_progress(), !content_loading() || content_loaded(), ms); - if (!_animation->radial.animating() && content_loaded()) { + DocumentData *document = getShownDocument(); + _animation->radial.update(document->progress(), !document->loading() || document->loaded(), ms); + if (!_animation->radial.animating() && document->loaded()) { delete _animation; - _animation = 0; + _animation = nullptr; } } } @@ -391,15 +326,15 @@ void Gif::clipCallback(ClipReaderNotification notification) { if (_gif->state() == ClipError) { delete _gif; _gif = BadClipReader; - content_forget(); + getShownDocument()->forget(); } else if (_gif->ready() && !_gif->started()) { int32 height = st::inlineMediaHeight; QSize frame = countFrameSize(); _gif->start(frame.width(), frame.height(), _width, height, false); } else if (_gif->paused() && !Ui::isInlineItemVisible(this)) { delete _gif; - _gif = 0; - content_forget(); + _gif = nullptr; + getShownDocument()->forget(); } } @@ -439,7 +374,7 @@ void Sticker::preload() const { } void Sticker::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { - bool loaded = content_loaded(); + bool loaded = getShownDocument()->loaded(); float64 over = _a_over.isNull() ? (_active ? 1 : 0) : _a_over.current(); if (over > 0) { @@ -519,7 +454,8 @@ Photo::Photo(Result *result) : ItemBase(result) { } void Photo::initDimensions() { - int32 w = content_width(), h = content_height(); + PhotoData *photo = getShownPhoto(); + int32 w = photo->full->width(), h = photo->full->height(); if (w <= 0 || h <= 0) { _maxw = 0; } else { @@ -530,8 +466,6 @@ void Photo::initDimensions() { } void Photo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { - bool loaded = content_loaded(); - int32 height = st::inlineMediaHeight; QSize frame = countFrameSize(); @@ -543,6 +477,9 @@ void Photo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCo } else { p.drawPixmap(r.topLeft(), _thumb); } + if (getShownPhoto()->full->toDelayedStorageImage()) { + p.fillRect(10, 10, 30, 30, QColor(255, 0, 0)); + } } void Photo::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { @@ -559,7 +496,8 @@ PhotoData *Photo::getShownPhoto() const { } QSize Photo::countFrameSize() const { - int32 framew = content_width(), frameh = content_height(), height = st::inlineMediaHeight; + PhotoData *photo = getShownPhoto(); + int32 framew = photo->full->width(), frameh = photo->full->height(), height = st::inlineMediaHeight; if (framew * height > frameh * _width) { if (framew < st::maxStickerSize || frameh > height) { if (frameh > height || (framew * height / frameh) <= st::maxStickerSize) { @@ -611,35 +549,6 @@ void Photo::prepareThumb(int32 width, int32 height, const QSize &frame) const { } } -int Photo::content_width() const { - if (PhotoData *photo = getShownPhoto()) { - return photo->full->width(); - } - return getResultWidth(); -} - -int Photo::content_height() const { - if (PhotoData *photo = getShownPhoto()) { - return photo->full->height(); - } - return getResultHeight(); -} - -bool Photo::content_loaded() const { - if (PhotoData *photo = getShownPhoto()) { - return photo->loaded(); - } - return _result->loaded(); -} - -void Photo::content_forget() { - if (PhotoData *photo = getShownPhoto()) { - photo->forget(); - } else { - _result->forget(); - } -} - Video::Video(Result *result) : FileBase(result) , _link(getResultContentUrlHandler()) , _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) @@ -651,7 +560,7 @@ Video::Video(Result *result) : FileBase(result) } void Video::initDimensions() { - bool withThumb = !content_thumb()->isNull(); + bool withThumb = !getShownDocument()->thumb->isNull(); _maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft; int32 textWidth = _maxw - (withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0); @@ -680,7 +589,7 @@ void Video::initDimensions() { void Video::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { int left = st::inlineThumbSize + st::inlineThumbSkip; - bool withThumb = !content_thumb()->isNull(); + bool withThumb = !getShownDocument()->thumb->isNull(); if (withThumb) { prepareThumb(st::inlineThumbSize, st::inlineThumbSize); if (_thumb.isNull()) { @@ -727,7 +636,7 @@ void Video::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, i } void Video::prepareThumb(int32 width, int32 height) const { - ImagePtr thumb = content_thumb(); + ImagePtr thumb = getShownDocument()->thumb; if (thumb->loaded()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { int32 w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1); @@ -781,11 +690,12 @@ void File::initDimensions() { void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const { int32 left = st::msgFileSize + st::inlineThumbSkip; - bool loaded = content_loaded(), displayLoading = content_displayLoading(); + DocumentData *document = getShownDocument(); + bool loaded = document->loaded(), displayLoading = document->displayLoading(); if (displayLoading) { ensureAnimation(); if (!_animation->radial.animating()) { - _animation->radial.start(content_progress()); + _animation->radial.start(document->progress()); } } bool showPause = false;// updateStatusText(parent); @@ -797,7 +707,7 @@ void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCon float64 over = _animation->a_thumbOver.current(); p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over)); } else { - bool over = ClickHandler::showAsActive(content_loading() ? _cancel : _open); + bool over = ClickHandler::showAsActive(document->loading() ? _cancel : _open); p.setBrush((over ? st::msgFileInBgOver : st::msgFileInBg)); } @@ -821,23 +731,12 @@ void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCon //} else { // icon = st::msgFileInDownload; //} - if (DocumentData *doc = getShownDocument()) { - if (doc->isImage()) { - icon = st::msgFileInImage; - } else if (doc->voice() || doc->song()) { - icon = st::msgFileInPlay; - } else { - icon = st::msgFileInFile; - } + if (document->isImage()) { + icon = st::msgFileInImage; + } else if (document->voice() || document->song()) { + icon = st::msgFileInPlay; } else { - QString mime = getResultContentType(); - if (mime.startsWith(qstr("image/"))) { - icon = st::msgFileInImage; - } else if (mime.startsWith(qstr("audio/"))) { - icon = st::msgFileInPlay; - } else { - icon = st::msgFileInFile; - } + icon = st::msgFileInFile; } p.drawSpriteCenter(iconCircle, icon); @@ -857,7 +756,7 @@ void File::paint(Painter &p, const QRect &clip, uint32 selection, const PaintCon void File::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const { if (x >= 0 && x < st::msgFileSize && y >= st::inlineRowMargin && y < st::inlineRowMargin + st::msgFileSize) { - link = content_loading() ? _cancel : _open; + link = getShownDocument()->loading() ? _cancel : _open; return; } if (x >= st::msgFileSize + st::inlineThumbSkip && x < _width && y >= 0 && y < _height) { @@ -868,7 +767,7 @@ void File::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, in void File::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { if (p == _open || p == _cancel) { - if (active && !content_loaded()) { + if (active && !getShownDocument()->loaded()) { ensureAnimation(); _animation->a_thumbOver.start(1); _animation->_a_thumbOver.start(); @@ -897,7 +796,8 @@ void File::step_radial(uint64 ms, bool timer) { if (timer) { Ui::repaintInlineItem(this); } else { - _animation->radial.update(content_progress(), content_loaded(), ms); + DocumentData *document = getShownDocument(); + _animation->radial.update(document->progress(), document->loaded(), ms); if (!_animation->radial.animating()) { checkAnimationFinished(); } @@ -914,7 +814,7 @@ void File::ensureAnimation() const { void File::checkAnimationFinished() { if (_animation && !_animation->_a_thumbOver.animating() && !_animation->radial.animating()) { - if (content_loaded()) { + if (getShownDocument()->loaded()) { _animation.clear(); } } diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h index 75649f8d6..93cd5e1fe 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h @@ -38,15 +38,7 @@ protected: int content_width() const; int content_height() const; - bool content_loading() const; - bool content_displayLoading() const; - bool content_loaded() const; - float64 content_progress() const; - void content_automaticLoad() const; - void content_forget(); FileLocation content_location() const; - QByteArray content_data() const; - ImagePtr content_thumb() const; int content_duration() const; }; @@ -151,11 +143,6 @@ private: QSize countFrameSize() const; - int content_width() const; - int content_height() const; - bool content_loaded() const; - void content_forget(); - mutable QPixmap _thumb; mutable bool _thumbLoaded = false; void prepareThumb(int32 width, int32 height, const QSize &frame) const; diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp index fe94d6c6a..b2c9e8c4e 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.cpp @@ -118,14 +118,6 @@ PhotoData *ItemBase::getResultPhoto() const { return _result ? _result->_photo : nullptr; } -int ItemBase::getResultWidth() const { - return _result ? _result->_width : 0; -} - -int ItemBase::getResultHeight() const { - return _result ? _result->_height : 0; -} - ImagePtr ItemBase::getResultThumb() const { if (_result) { if (_result->_photo && !_result->_photo->thumb->isNull()) { @@ -187,9 +179,5 @@ QString ItemBase::getResultThumbLetter() const { return QString(); } -QString ItemBase::getResultContentType() const { - return _result->_content_type; -} - } // namespace Layout } // namespace InlineBots diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h index b2846297d..7c3dc855b 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_item.h @@ -95,8 +95,6 @@ public: protected: DocumentData *getResultDocument() const; PhotoData *getResultPhoto() const; - int getResultWidth() const; - int getResultHeight() const; ImagePtr getResultThumb() const; QPixmap getResultContactAvatar(int width, int height) const; int getResultDuration() const; @@ -104,7 +102,6 @@ protected: ClickHandlerPtr getResultUrlHandler() const; ClickHandlerPtr getResultContentUrlHandler() const; QString getResultThumbLetter() const; - QString getResultContentType() const; Result *_result = nullptr; DocumentData *_doc = nullptr; diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp index a31d807f4..a315504e8 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.cpp @@ -24,6 +24,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "inline_bots/inline_bot_layout_item.h" #include "inline_bots/inline_bot_send_data.h" #include "mtproto/file_download.h" +#include "ui/filedialog.h" #include "mainwidget.h" namespace InlineBots { @@ -103,8 +104,8 @@ UniquePointer Result::create(uint64 queryId, const MTPBotInlineResult &m if (r.has_w()) result->_width = r.vw.v; if (r.has_h()) result->_height = r.vh.v; if (r.has_duration()) result->_duration = r.vduration.v; - if (!result->_thumb_url.isEmpty() && (result->_thumb_url.startsWith(qstr("http://"), Qt::CaseInsensitive) || result->_thumb_url.startsWith(qstr("https://"), Qt::CaseInsensitive))) { - result->_thumb = ImagePtr(result->_thumb_url); + if (!result->_thumb_url.startsWith(qstr("http://"), Qt::CaseInsensitive) && !result->_thumb_url.startsWith(qstr("https://"), Qt::CaseInsensitive)) { + result->_thumb_url = QString(); } message = &r.vsend_message; } break; @@ -132,12 +133,11 @@ UniquePointer Result::create(uint64 queryId, const MTPBotInlineResult &m case mtpc_botInlineMessageMediaAuto: { const auto &r(message->c_botInlineMessageMediaAuto()); if (result->_type == Type::Photo) { - result->sendData.reset(new internal::SendPhoto(result->_photo, result->_content_url, qs(r.vcaption))); + result->createPhoto(); + result->sendData.reset(new internal::SendPhoto(result->_photo, qs(r.vcaption))); } else { - if (!result->_document) { - - } - result->sendData.reset(new internal::SendFile(result->_document, result->_content_url, qs(r.vcaption))); + result->createDocument(); + result->sendData.reset(new internal::SendFile(result->_document, qs(r.vcaption))); } if (r.has_reply_markup()) { result->_mtpKeyboard = MakeUnique(r.vreply_markup); @@ -194,6 +194,9 @@ UniquePointer Result::create(uint64 queryId, const MTPBotInlineResult &m return UniquePointer(); } + if (result->_thumb->isNull() && !result->_thumb_url.isEmpty()) { + result->_thumb = ImagePtr(result->_thumb_url); + } LocationCoords location; if (result->getLocationCoords(&location)) { int32 w = st::inlineThumbSize, h = st::inlineThumbSize; @@ -238,196 +241,11 @@ bool Result::onChoose(Layout::ItemBase *layout) { return true; } } - if (_type == Type::Photo) { - if (_thumb->loaded()) { - return true; - } else if (!_thumb->loading()) { - _thumb->loadEvenCancelled(); - Ui::repaintInlineItem(layout); - } - } else if (_type == Type::Gif) { - if (loaded()) { - return true; - } else if (loading()) { - cancelFile(); - Ui::repaintInlineItem(layout); - } else { - saveFile(QString(), LoadFromCloudOrLocal, false); - Ui::repaintInlineItem(layout); - } - } else { - return true; - } - return false; -} - -void Result::automaticLoadGif() { - if (loaded() || _type != Type::Gif) { - return; - } - if (_content_type != qstr("video/mp4") && _content_type != qstr("image/gif")) { - return; - } - - if (_loader != CancelledWebFileLoader) { - // if load at least anywhere - bool loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate) || !(cAutoDownloadGif() & dbiadNoGroups); - saveFile(QString(), loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true); - } -} - -void Result::automaticLoadSettingsChangedGif() { - if (loaded() || _loader != CancelledWebFileLoader) return; - _loader = nullptr; -} - -void Result::saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading) { - if (loaded()) { - return; - } - - if (_loader == CancelledWebFileLoader) _loader = nullptr; - if (_loader) { - if (!_loader->setFileName(toFile)) { - cancelFile(); - _loader = nullptr; - } - } - - if (_loader) { - if (fromCloud == LoadFromCloudOrLocal) _loader->permitLoadFromCloud(); - } else { - _loader = new webFileLoader(_content_url, toFile, fromCloud, autoLoading); - regLoader(_loader, this); - - _loader->connect(_loader, SIGNAL(progress(FileLoader*)), App::main(), SLOT(inlineResultLoadProgress(FileLoader*))); - _loader->connect(_loader, SIGNAL(failed(FileLoader*, bool)), App::main(), SLOT(inlineResultLoadFailed(FileLoader*, bool))); - _loader->start(); - } -} - -void Result::openFile() { - //if (loaded()) { - // bool playVoice = data->voice() && audioPlayer() && item; - // bool playMusic = data->song() && audioPlayer() && item; - // bool playAnimation = data->isAnimation() && item && item->getMedia(); - // const FileLocation &location(data->location(true)); - // if (!location.isEmpty() || (!data->data().isEmpty() && (playVoice || playMusic || playAnimation))) { - // if (playVoice) { - // AudioMsgId playing; - // AudioPlayerState playingState = AudioPlayerStopped; - // audioPlayer()->currentState(&playing, &playingState); - // if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { - // audioPlayer()->pauseresume(OverviewVoiceFiles); - // } else { - // AudioMsgId audio(data, item->fullId()); - // audioPlayer()->play(audio); - // if (App::main()) { - // App::main()->audioPlayProgress(audio); - // App::main()->mediaMarkRead(data); - // } - // } - // } else if (playMusic) { - // SongMsgId playing; - // AudioPlayerState playingState = AudioPlayerStopped; - // audioPlayer()->currentState(&playing, &playingState); - // if (playing.msgId == item->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) { - // audioPlayer()->pauseresume(OverviewFiles); - // } else { - // SongMsgId song(data, item->fullId()); - // audioPlayer()->play(song); - // if (App::main()) App::main()->documentPlayProgress(song); - // } - // } else if (data->voice() || data->isVideo()) { - // psOpenFile(location.name()); - // if (App::main()) App::main()->mediaMarkRead(data); - // } else if (data->size < MediaViewImageSizeLimit) { - // if (!data->data().isEmpty() && playAnimation) { - // if (action == ActionOnLoadPlayInline && item->getMedia()) { - // item->getMedia()->playInline(item); - // } else { - // App::wnd()->showDocument(data, item); - // } - // } else if (location.accessEnable()) { - // if (item && (data->isAnimation() || QImageReader(location.name()).canRead())) { - // if (action == ActionOnLoadPlayInline && item->getMedia()) { - // item->getMedia()->playInline(item); - // } else { - // App::wnd()->showDocument(data, item); - // } - // } else { - // psOpenFile(location.name()); - // } - // location.accessDisable(); - // } else { - // psOpenFile(location.name()); - // } - // } else { - // psOpenFile(location.name()); - // } - // return; - // } - //} - - //QString filename = documentSaveFilename(data); - //if (filename.isEmpty()) return; - //if (!data->saveToCache()) { - // filename = documentSaveFilename(data); - // if (filename.isEmpty()) return; - //} - - //saveFile() - //data->save(filename, action, item ? item->fullId() : FullMsgId()); -} - -void Result::cancelFile() { - if (!loading()) return; - - unregLoader(_loader); - - webFileLoader *l = _loader; - _loader = CancelledWebFileLoader; - if (l) { - l->cancel(); - l->deleteLater(); - l->stop(); - } -} - -QByteArray Result::data() const { - return _data; -} - -bool Result::loading() const { - return _loader && _loader != CancelledWebFileLoader; -} - -bool Result::loaded() const { - if (loading() && _loader->done()) { - unregLoader(_loader); - if (_loader->fileType() == mtpc_storage_fileUnknown) { - _loader->deleteLater(); - _loader->stop(); - _loader = CancelledWebFileLoader; - } else { - Result *that = const_cast(this); - that->_data = _loader->bytes(); - - _loader->deleteLater(); - _loader->stop(); - _loader = nullptr; - } - } - return !_data.isEmpty(); -} - -bool Result::displayLoading() const { - return loading() ? (!_loader->loadingLocal() || !_loader->autoLoading()) : false; + return true; } void Result::forget() { _thumb->forget(); - _data.clear(); if (_document) { _document->forget(); } @@ -436,8 +254,20 @@ void Result::forget() { } } -float64 Result::progress() const { - return loading() ? _loader->currentProgress() : (loaded() ? 1 : 0); return false; +void Result::openFile() { + if (_document) { + DocumentOpenClickHandler(_document).onClick(Qt::LeftButton); + } else if (_photo) { + PhotoOpenClickHandler(_photo).onClick(Qt::LeftButton); + } +} + +void Result::cancelFile() { + if (_document) { + DocumentCancelClickHandler(_document).onClick(Qt::LeftButton); + } else if (_photo) { + PhotoCancelClickHandler(_photo).onClick(Qt::LeftButton); + } } bool Result::hasThumbDisplay() const { @@ -476,8 +306,66 @@ QString Result::getLayoutDescription() const { return sendData->getLayoutDescription(this); } +void Result::createPhoto() { + if (_photo) return; + + if (_thumb_url.isEmpty()) { + QSize thumb = shrinkToKeepAspect(_width, _height, 100, 100); + _thumb = ImagePtr(thumb.width(), thumb.height()); + } else { + _thumb = ImagePtr(_thumb_url, QSize(100, 100)); + } + ImagePtr medium = ImagePtr(_content_url, QSize(320, 320)); + + uint64 photoId = rand_value(); + _photo = App::photoSet(photoId, 0, 0, unixtime(), _thumb, medium, ImagePtr(_width, _height)); + _photo->thumb = _thumb; +} + +void Result::createDocument() { + if (_document) return; + + uint64 docId = rand_value(); + + if (!_thumb_url.isEmpty()) { + _thumb = ImagePtr(_thumb_url, QSize(90, 90)); + } + + QString mime = _content_type; + + QVector attributes; + QSize dimensions(_width, _height); + if (_type == Type::Gif) { + const char *filename = (mime == qstr("video/mp4") ? "animation.gif.mp4" : "animation.gif"); + attributes.push_back(MTP_documentAttributeFilename(MTP_string(filename))); + attributes.push_back(MTP_documentAttributeAnimated()); + attributes.push_back(MTP_documentAttributeVideo(MTP_int(_duration), MTP_int(_width), MTP_int(_height))); + } else if (_type == Type::Video) { + attributes.push_back(MTP_documentAttributeVideo(MTP_int(_duration), MTP_int(_width), MTP_int(_height))); + } else if (_type == Type::Audio) { + MTPDdocumentAttributeAudio::Flags flags = 0; + if (mime == qstr("audio/ogg")) { + flags |= MTPDdocumentAttributeAudio::Flag::f_voice; + } else { + QStringList p = mimeTypeForName(mime).globPatterns(); + QString pattern = p.isEmpty() ? QString() : p.front(); + QString extension = pattern.isEmpty() ? qsl(".unknown") : pattern.replace('*', QString()); + QString filename = filedialogDefaultName(qsl("inline"), extension, QString(), true); + attributes.push_back(MTP_documentAttributeFilename(MTP_string(filename))); + } + attributes.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(_duration), MTPstring(), MTPstring(), MTPbytes())); + } + + MTPDocument document = MTP_document(MTP_long(docId), MTP_long(0), MTP_int(unixtime()), MTP_string(mime), MTP_int(0), MTP_photoSizeEmpty(MTP_string("")), MTP_int(MTP::maindc()), MTP_vector(attributes)); + + _document = App::feedDocument(document); + _document->setContentUrl(_content_url); + if (!_thumb->isNull()) { + _document->thumb = _thumb; + } +} + Result::~Result() { - cancelFile(); } } // namespace InlineBots diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_result.h b/Telegram/SourceFiles/inline_bots/inline_bot_result.h index 22f60e91d..f368e6c87 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_result.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_result.h @@ -61,19 +61,10 @@ public: // inline bot result. If it returns true you need to send this result. bool onChoose(Layout::ItemBase *layout); - void automaticLoadGif(); - void automaticLoadSettingsChangedGif(); - void saveFile(const QString &toFile, LoadFromCloudSetting fromCloud, bool autoLoading); + void forget(); void openFile(); void cancelFile(); - QByteArray data() const; - bool loading() const; - bool loaded() const; - bool displayLoading() const; - void forget(); - float64 progress() const; - bool hasThumbDisplay() const; void addToHistory(History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId) const; @@ -86,6 +77,7 @@ public: ~Result(); private: + void createPhoto(); void createDocument(); enum class Type { @@ -126,9 +118,6 @@ private: UniquePointer sendData; - QByteArray _data; - mutable webFileLoader *_loader = nullptr; - }; Result *getResultFromLoader(FileLoader *loader); diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp index 4636fa8d9..d2f5354ec 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp @@ -35,44 +35,6 @@ QString SendData::getLayoutDescription(const Result *owner) const { return owner->_description; } -ImagePtr SendData::getResultThumb(const Result *owner) const { - return owner->_thumb; -} - -int SendData::getResultWidth(const Result *owner) const { - return owner->_width; -} - -int SendData::getResultHeight(const Result *owner) const { - return owner->_height; -} - -QString SendData::getResultMime(const Result *owner) const { - return owner->_content_type; -} - -QVector SendData::prepareResultAttributes(const Result *owner) const { - QVector result; - int duration = owner->_duration; - QSize dimensions(owner->_width, owner->_height); - using Type = Result::Type; - if (owner->_type == Type::Gif) { - const char *filename = (owner->_content_type == qstr("video/mp4") ? "animation.gif.mp4" : "animation.gif"); - result.push_back(MTP_documentAttributeFilename(MTP_string(filename))); - result.push_back(MTP_documentAttributeAnimated()); - result.push_back(MTP_documentAttributeVideo(MTP_int(owner->_duration), MTP_int(owner->_width), MTP_int(owner->_height))); - } else if (owner->_type == Type::Video) { - result.push_back(MTP_documentAttributeVideo(MTP_int(owner->_duration), MTP_int(owner->_width), MTP_int(owner->_height))); - } else if (owner->_type == Type::Audio) { - MTPDdocumentAttributeAudio::Flags flags = 0; - if (owner->_content_type == qstr("audio/ogg")) { - flags |= MTPDdocumentAttributeAudio::Flag::f_voice; - } - result.push_back(MTP_documentAttributeAudio(MTP_flags(flags), MTP_int(owner->_duration), MTPstring(), MTPstring(), MTPbytes())); - } - return result; -} - void SendDataCommon::addToHistory(const Result *owner, History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const { @@ -119,76 +81,13 @@ QString SendContact::getLayoutDescription(const Result *owner) const { void SendPhoto::addToHistory(const Result *owner, History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const { - if (_photo) { - history->addNewPhoto(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _photo, _caption, markup); - return; - } - - ImagePtr resultThumb = getResultThumb(owner); - QImage fileThumb(resultThumb->pix().toImage()); - - QVector photoSizes; - - QPixmap thumb = (fileThumb.width() > 100 || fileThumb.height() > 100) ? QPixmap::fromImage(fileThumb.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fileThumb); - ImagePtr thumbPtr = ImagePtr(thumb, "JPG"); - photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0))); - - QSize medium = resizeKeepAspect(getResultWidth(owner), getResultHeight(owner), 320, 320); - photoSizes.push_back(MTP_photoSize(MTP_string("m"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0))); - - photoSizes.push_back(MTP_photoSize(MTP_string("x"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(getResultWidth(owner)), MTP_int(getResultHeight(owner)), MTP_int(0))); - - uint64 photoId = rand_value(); - PhotoData *ph = App::photoSet(photoId, 0, 0, unixtime(), thumbPtr, ImagePtr(medium.width(), medium.height()), ImagePtr(getResultWidth(owner), getResultHeight(owner))); - MTPPhoto photo = MTP_photo(MTP_long(photoId), MTP_long(0), MTP_int(ph->date), MTP_vector(photoSizes)); - - MTPMessageMedia media = MTP_messageMediaPhoto(photo, MTP_string(_caption)); - history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(msgId), MTP_int(fromId), peerToMTP(history->peer->id), MTPnullFwdHeader, MTP_int(viaBotId), MTP_int(replyToId), mtpDate, MTP_string(""), media, markup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); + history->addNewPhoto(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _photo, _caption, markup); } void SendFile::addToHistory(const Result *owner, History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId, const MTPReplyMarkup &markup) const { - if (_document) { - history->addNewDocument(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _document, _caption, markup); - return; - } - - uint64 docId = rand_value(); - - ImagePtr resultThumb = getResultThumb(owner); - MTPPhotoSize thumbSize; - QPixmap thumb; - int tw = resultThumb->width(), th = resultThumb->height(); - if (!resultThumb->isNull() && tw > 0 && th > 0 && tw < 20 * th && th < 20 * tw && resultThumb->loaded()) { - if (tw > th) { - if (tw > 90) { - th = th * 90 / tw; - tw = 90; - } - } else if (th > 90) { - tw = tw * 90 / th; - th = 90; - } - thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(tw), MTP_int(th), MTP_int(0)); - thumb = resultThumb->pixNoCache(tw, th, ImagePixSmooth); - } else { - tw = th = 0; - thumbSize = MTP_photoSizeEmpty(MTP_string("")); - } - - QVector attributes = prepareResultAttributes(owner); - MTPDocument document = MTP_document(MTP_long(docId), MTP_long(0), MTP_int(unixtime()), MTP_string(getResultMime(owner)), MTP_int(owner->data().size()), thumbSize, MTP_int(MTP::maindc()), MTP_vector(attributes)); - - if (!owner->data().isEmpty()) { - Local::writeStickerImage(mediaKey(DocumentFileLocation, MTP::maindc(), docId), owner->data()); - } - - if (tw > 0 && th > 0) { - App::feedDocument(document, thumb); - } - MTPMessageMedia media = MTP_messageMediaDocument(document, MTP_string(_caption)); - history->addNewMessage(MTP_message(MTP_flags(flags), MTP_int(msgId), MTP_int(fromId), peerToMTP(history->peer->id), MTPnullFwdHeader, MTP_int(viaBotId), MTP_int(replyToId), mtpDate, MTP_string(""), media, markup, MTPnullEntities, MTP_int(1), MTPint()), NewMessageUnread); + history->addNewDocument(msgId, flags, viaBotId, replyToId, date(mtpDate), fromId, _document, _caption, markup); } } // namespace internal diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h index 47c655905..2030a01be 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.h @@ -55,17 +55,6 @@ public: virtual QString getLayoutTitle(const Result *owner) const; virtual QString getLayoutDescription(const Result *owner) const; -protected: - - ImagePtr getResultThumb(const Result *owner) const; - int getResultWidth(const Result *owner) const; - int getResultHeight(const Result *owner) const; - QString getResultMime(const Result *owner) const; - QVector prepareResultAttributes(const Result *owner) const; - - void setResultDocument(const Result *owner, DocumentData *document) const; - void setResultPhoto(const Result *owner, PhotoData *photo) const; - }; // This class implements addHistory() for most of the types hiding @@ -191,14 +180,13 @@ private: // Message with photo. class SendPhoto : public SendData { public: - SendPhoto(PhotoData *photo, const QString &url, const QString &caption) + SendPhoto(PhotoData *photo, const QString &caption) : _photo(photo) - , _url(url) , _caption(caption) { } bool isValid() const override { - return _photo || !_url.isEmpty(); + return _photo != nullptr; } void addToHistory(const Result *owner, History *history, @@ -207,21 +195,20 @@ public: private: PhotoData *_photo; - QString _url, _caption; + QString _caption; }; // Message with file. class SendFile : public SendData { public: - SendFile(DocumentData *document, const QString &url, const QString &caption) + SendFile(DocumentData *document, const QString &caption) : _document(document) - , _url(url) , _caption(caption) { } bool isValid() const override { - return _document || !_url.isEmpty(); + return _document != nullptr; } void addToHistory(const Result *owner, History *history, @@ -230,7 +217,7 @@ public: private: DocumentData *_document; - QString _url, _caption; + QString _caption; }; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index c9f83e15c..7b470f7e9 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -838,10 +838,6 @@ void MainWidget::notify_historyItemLayoutChanged(const HistoryItem *item) { if (overview) overview->notify_historyItemLayoutChanged(item); } -void MainWidget::notify_automaticLoadSettingsChangedGif() { - history.notify_automaticLoadSettingsChangedGif(); -} - void MainWidget::notify_handlePendingHistoryUpdate() { history.notify_handlePendingHistoryUpdate(); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index e054e50ff..557819b76 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -465,7 +465,6 @@ public: void notify_migrateUpdated(PeerData *peer); void notify_clipStopperHidden(ClipStopperType type); void notify_historyItemLayoutChanged(const HistoryItem *item); - void notify_automaticLoadSettingsChangedGif(); void notify_handlePendingHistoryUpdate(); void cmd_search(); diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 7db85accc..b8cc0eea3 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1088,8 +1088,11 @@ public: void setRemoteLocation(int32 dc, uint64 access); void setContentUrl(const QString &url); + bool hasRemoteLocation() const { + return (_dc != 0 && _access != 0); + } bool isValid() const { - return (_dc != 0 && _access != 0) || !_url.isEmpty(); + return hasRemoteLocation() || !_url.isEmpty(); } MTPInputDocument mtpInput() const { if (_access) { diff --git a/Telegram/SourceFiles/ui/images.cpp b/Telegram/SourceFiles/ui/images.cpp index c56a5b75e..0bad4ce50 100644 --- a/Telegram/SourceFiles/ui/images.cpp +++ b/Telegram/SourceFiles/ui/images.cpp @@ -34,7 +34,7 @@ namespace { WebImages webImages; Image *blank() { - static Image *img = getImage(qsl(":/gui/art/blank.gif"), "GIF"); + static Image *img = internal::getImage(qsl(":/gui/art/blank.gif"), "GIF"); return img; } @@ -60,7 +60,7 @@ ImagePtr::ImagePtr() : Parent(blank()) { } ImagePtr::ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def) : - Parent((location.type() == mtpc_fileLocation) ? (Image*)(getImage(StorageImageLocation(width, height, location.c_fileLocation()))) : def.v()) { + Parent((location.type() == mtpc_fileLocation) ? (Image*)(internal::getImage(StorageImageLocation(width, height, location.c_fileLocation()))) : def.v()) { } Image::Image(const QString &file, QByteArray fmt) : _forgot(false) { @@ -661,41 +661,6 @@ Image::~Image() { } } -Image *getImage(const QString &file, QByteArray format) { - if (file.startsWith(qstr("http://"), Qt::CaseInsensitive) || file.startsWith(qstr("https://"), Qt::CaseInsensitive)) { - QString key = file; - WebImages::const_iterator i = webImages.constFind(key); - if (i == webImages.cend()) { - i = webImages.insert(key, new WebImage(file)); - } - return i.value(); - } else { - QFileInfo f(file); - QString key = qsl("//:%1//:%2//:").arg(f.size()).arg(f.lastModified().toTime_t()) + file; - LocalImages::const_iterator i = localImages.constFind(key); - if (i == localImages.cend()) { - i = localImages.insert(key, new Image(file, format)); - } - return i.value(); - } -} - -Image *getImage(const QByteArray &filecontent, QByteArray format) { - return new Image(filecontent, format); -} - -Image *getImage(const QPixmap &pixmap, QByteArray format) { - return new Image(pixmap, format); -} - -Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap) { - return new Image(filecontent, format, pixmap); -} - -Image *getImage(int32 width, int32 height) { - return new DelayedStorageImage(width, height); -} - void clearStorageImages() { for (StorageImages::const_iterator i = storageImages.cbegin(), e = storageImages.cend(); i != e; ++i) { delete i.value(); @@ -976,33 +941,7 @@ void DelayedStorageImage::cancel() { StorageImage::cancel(); } -StorageImage *getImage(const StorageImageLocation &location, int32 size) { - StorageKey key(storageKey(location)); - StorageImages::const_iterator i = storageImages.constFind(key); - if (i == storageImages.cend()) { - i = storageImages.insert(key, new StorageImage(location, size)); - } - return i.value(); -} - -StorageImage *getImage(const StorageImageLocation &location, const QByteArray &bytes) { - StorageKey key(storageKey(location)); - StorageImages::const_iterator i = storageImages.constFind(key); - if (i == storageImages.cend()) { - QByteArray bytesArr(bytes); - i = storageImages.insert(key, new StorageImage(location, bytesArr)); - } else if (!i.value()->loaded()) { - QByteArray bytesArr(bytes); - i.value()->setData(bytesArr); - if (!location.isNull()) { - Local::writeImage(key, StorageImageSaved(mtpToStorageType(mtpc_storage_filePartial), bytes)); - } - } - return i.value(); -} - - -WebImage::WebImage(const QString &url) : _url(url), _size(0), _width(0), _height(0) { +WebImage::WebImage(const QString &url, QSize box) : _url(url), _box(box), _size(0), _width(0), _height(0) { } int32 WebImage::countWidth() const { @@ -1015,14 +954,93 @@ int32 WebImage::countHeight() const { void WebImage::setInformation(int32 size, int32 width, int32 height) { _size = size; - _width = width; - _height = height; + if (!_box.isEmpty()) { + QSize final = shrinkToKeepAspect(width, height, _box.width(), _box.height()); + _width = final.width(); + _height = final.height(); + } else { + _width = width; + _height = height; + } } FileLoader *WebImage::createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) { return new webFileLoader(_url, QString(), fromCloud, autoLoading); } +namespace internal { + +Image *getImage(const QString &file, QByteArray format) { + if (file.startsWith(qstr("http://"), Qt::CaseInsensitive) || file.startsWith(qstr("https://"), Qt::CaseInsensitive)) { + QString key = file; + WebImages::const_iterator i = webImages.constFind(key); + if (i == webImages.cend()) { + i = webImages.insert(key, new WebImage(file)); + } + return i.value(); + } else { + QFileInfo f(file); + QString key = qsl("//:%1//:%2//:").arg(f.size()).arg(f.lastModified().toTime_t()) + file; + LocalImages::const_iterator i = localImages.constFind(key); + if (i == localImages.cend()) { + i = localImages.insert(key, new Image(file, format)); + } + return i.value(); + } +} + +Image *getImage(const QString &url, QSize box) { + QString key = qsl("//:%1//:%2//:").arg(box.width()).arg(box.height()) + url; + auto i = webImages.constFind(key); + if (i == webImages.cend()) { + i = webImages.insert(key, new WebImage(url, box)); + } + return i.value(); +} + +Image *getImage(const QByteArray &filecontent, QByteArray format) { + return new Image(filecontent, format); +} + +Image *getImage(const QPixmap &pixmap, QByteArray format) { + return new Image(pixmap, format); +} + +Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap) { + return new Image(filecontent, format, pixmap); +} + +Image *getImage(int32 width, int32 height) { + return new DelayedStorageImage(width, height); +} + +StorageImage *getImage(const StorageImageLocation &location, int32 size) { + StorageKey key(storageKey(location)); + StorageImages::const_iterator i = storageImages.constFind(key); + if (i == storageImages.cend()) { + i = storageImages.insert(key, new StorageImage(location, size)); + } + return i.value(); +} + +StorageImage *getImage(const StorageImageLocation &location, const QByteArray &bytes) { + StorageKey key(storageKey(location)); + StorageImages::const_iterator i = storageImages.constFind(key); + if (i == storageImages.cend()) { + QByteArray bytesArr(bytes); + i = storageImages.insert(key, new StorageImage(location, bytesArr)); + } else if (!i.value()->loaded()) { + QByteArray bytesArr(bytes); + i.value()->setData(bytesArr); + if (!location.isNull()) { + Local::writeImage(key, StorageImageSaved(mtpToStorageType(mtpc_storage_filePartial), bytes)); + } + } + return i.value(); +} + +} // namespace internal + ReadAccessEnabler::ReadAccessEnabler(const PsFileBookmark *bookmark) : _bookmark(bookmark), _failed(_bookmark ? !_bookmark->enable() : false) { } diff --git a/Telegram/SourceFiles/ui/images.h b/Telegram/SourceFiles/ui/images.h index 0622dca27..83a346517 100644 --- a/Telegram/SourceFiles/ui/images.h +++ b/Telegram/SourceFiles/ui/images.h @@ -231,12 +231,6 @@ private: }; -Image *getImage(const QString &file, QByteArray format); -Image *getImage(const QByteArray &filecontent, QByteArray format); -Image *getImage(const QPixmap &pixmap, QByteArray format); -Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap); -Image *getImage(int32 width, int32 height); - typedef QPair StorageKey; inline uint64 storageMix32To64(int32 a, int32 b) { return (uint64(*reinterpret_cast(&a)) << 32) | uint64(*reinterpret_cast(&b)); @@ -300,10 +294,10 @@ public: StorageImage(const StorageImageLocation &location, int32 size = 0); StorageImage(const StorageImageLocation &location, QByteArray &bytes); - virtual void setInformation(int32 size, int32 width, int32 height); - virtual FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading); + void setInformation(int32 size, int32 width, int32 height) override; + FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) override; - virtual const StorageImageLocation &location() const { + const StorageImageLocation &location() const override { return _location; } @@ -311,8 +305,8 @@ protected: StorageImageLocation _location; int32 _size; - virtual int32 countWidth() const; - virtual int32 countHeight() const; + int32 countWidth() const override; + int32 countHeight() const override; }; @@ -349,52 +343,61 @@ private: }; -StorageImage *getImage(const StorageImageLocation &location, int32 size = 0); -StorageImage *getImage(const StorageImageLocation &location, const QByteArray &bytes); -Image *getImage(int32 width, int32 height, const MTPFileLocation &location); - class WebImage : public RemoteImage { public: - WebImage(const QString &url); + // If !box.isEmpty() then resize the image to fit in this box. + WebImage(const QString &url, QSize box = QSize()); - virtual void setInformation(int32 size, int32 width, int32 height); - virtual FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading); + void setInformation(int32 size, int32 width, int32 height) override; + FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) override; protected: - virtual int32 countWidth() const; - virtual int32 countHeight() const; + int32 countWidth() const override; + int32 countHeight() const override; private: QString _url; + QSize _box; int32 _size, _width, _height; }; -WebImage *getImage(const QUrl &url); +namespace internal { + Image *getImage(const QString &file, QByteArray format); + Image *getImage(const QString &url, QSize box); + Image *getImage(const QByteArray &filecontent, QByteArray format); + Image *getImage(const QPixmap &pixmap, QByteArray format); + Image *getImage(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap); + Image *getImage(int32 width, int32 height); + StorageImage *getImage(const StorageImageLocation &location, int32 size = 0); + StorageImage *getImage(const StorageImageLocation &location, const QByteArray &bytes); +} // namespace internal class ImagePtr : public ManagedPtr { public: ImagePtr(); - ImagePtr(const QString &file, QByteArray format = QByteArray()) : Parent(getImage(file, format)) { + ImagePtr(const QString &file, QByteArray format = QByteArray()) : Parent(internal::getImage(file, format)) { } - ImagePtr(const QByteArray &filecontent, QByteArray format = QByteArray()) : Parent(getImage(filecontent, format)) { + ImagePtr(const QString &url, QSize box) : Parent(internal::getImage(url, box)) { } - ImagePtr(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap) : Parent(getImage(filecontent, format, pixmap)) { + ImagePtr(const QByteArray &filecontent, QByteArray format = QByteArray()) : Parent(internal::getImage(filecontent, format)) { } - ImagePtr(const QPixmap &pixmap, QByteArray format) : Parent(getImage(pixmap, format)) { + ImagePtr(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap) : Parent(internal::getImage(filecontent, format, pixmap)) { } - ImagePtr(const StorageImageLocation &location, int32 size = 0) : Parent(getImage(location, size)) { + ImagePtr(const QPixmap &pixmap, QByteArray format) : Parent(internal::getImage(pixmap, format)) { } - ImagePtr(const StorageImageLocation &location, const QByteArray &bytes) : Parent(getImage(location, bytes)) { + ImagePtr(const StorageImageLocation &location, int32 size = 0) : Parent(internal::getImage(location, size)) { + } + ImagePtr(const StorageImageLocation &location, const QByteArray &bytes) : Parent(internal::getImage(location, bytes)) { } ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def = ImagePtr()); - ImagePtr(int32 width, int32 height) : Parent(getImage(width, height)) { + ImagePtr(int32 width, int32 height) : Parent(internal::getImage(width, height)) { } }; -inline QSize resizeKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) { +inline QSize shrinkToKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) { int32 w = qMax(width, 1), h = qMax(height, 1); if (w * toheight > h * towidth) { h = qRound(h * towidth / float64(w));