Pass FileOrigin in all file downloads.

This commit is contained in:
John Preston 2018-07-14 00:25:47 +03:00
parent ee16070abe
commit 839885910c
67 changed files with 1021 additions and 510 deletions

View file

@ -190,7 +190,7 @@ inputPhoto#3bb3b94a id:long access_hash:long file_reference:bytes = InputPhoto;
inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation; inputFileLocation#dfdaabe1 volume_id:long local_id:int secret:long file_reference:bytes = InputFileLocation;
inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation; inputEncryptedFileLocation#f5235d55 id:long access_hash:long = InputFileLocation;
inputDocumentFileLocation#a9b915b0 id:long access_hash:long version:int file_reference:bytes = InputFileLocation; inputDocumentFileLocation#196683d9 id:long access_hash:long file_reference:bytes = InputFileLocation;
inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation; inputSecureFileLocation#cbc7ee28 id:long access_hash:long = InputFileLocation;
inputTakeoutFileLocation#29be5899 = InputFileLocation; inputTakeoutFileLocation#29be5899 = InputFileLocation;
@ -508,7 +508,7 @@ inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument; inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
documentEmpty#36f8c871 id:long = Document; documentEmpty#36f8c871 id:long = Document;
document#ca84c039 id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumb:PhotoSize dc_id:int version:int attributes:Vector<DocumentAttribute> = Document; document#59534e4c id:long access_hash:long file_reference:bytes date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = Document;
help.support#17c6b5f6 phone_number:string user:User = help.Support; help.support#17c6b5f6 phone_number:string user:User = help.Support;
@ -1331,4 +1331,4 @@ langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<strin
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference; langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>; langpack.getLanguages#42c6978f lang_pack:string = Vector<LangPackLanguage>;
// LAYER 85 // LAYER 86

View file

@ -157,7 +157,7 @@ void BackgroundBox::Inner::updateWallpapers() {
for (int i = 0; i < BackgroundsInRow * 3; ++i) { for (int i = 0; i < BackgroundsInRow * 3; ++i) {
if (i >= _bgCount) break; if (i >= _bgCount) break;
App::cServerBackgrounds().at(i).thumb->load(); App::cServerBackgrounds()[i].thumb->load(Data::FileOrigin());
} }
} }
@ -172,13 +172,16 @@ void BackgroundBox::Inner::paintEvent(QPaintEvent *e) {
int index = i * BackgroundsInRow + j; int index = i * BackgroundsInRow + j;
if (index >= _bgCount) break; if (index >= _bgCount) break;
const App::WallPaper &paper(App::cServerBackgrounds().at(index)); const auto &paper = App::cServerBackgrounds()[index];
paper.thumb->load(); paper.thumb->load(Data::FileOrigin());
int x = st::backgroundPadding + j * (st::backgroundSize.width() + st::backgroundPadding); int x = st::backgroundPadding + j * (st::backgroundSize.width() + st::backgroundPadding);
int y = st::backgroundPadding + i * (st::backgroundSize.height() + st::backgroundPadding); int y = st::backgroundPadding + i * (st::backgroundSize.height() + st::backgroundPadding);
const QPixmap &pix(paper.thumb->pix(st::backgroundSize.width(), st::backgroundSize.height())); const auto &pix = paper.thumb->pix(
Data::FileOrigin(),
st::backgroundSize.width(),
st::backgroundSize.height());
p.drawPixmap(x, y, pix); p.drawPixmap(x, y, pix);
if (paper.id == Window::Theme::Background()->id()) { if (paper.id == Window::Theme::Background()->id()) {

View file

@ -648,7 +648,13 @@ void DeleteMessagesBox::deleteAndClear() {
Auth().data().sendHistoryChangeNotifications(); Auth().data().sendHistoryChangeNotifications();
} }
ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, bool isChannel, const MTPChatPhoto &photo, int count, const QVector<UserData*> &participants) ConfirmInviteBox::ConfirmInviteBox(
QWidget*,
const QString &title,
bool isChannel,
const MTPChatPhoto &photo,
int count,
const QVector<UserData*> &participants)
: _title(this, st::confirmInviteTitle) : _title(this, st::confirmInviteTitle)
, _status(this, st::confirmInviteStatus) , _status(this, st::confirmInviteStatus)
, _participants(participants) { , _participants(participants) {
@ -675,7 +681,7 @@ ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, bool isChanne
_photo = ImagePtr(location); _photo = ImagePtr(location);
if (!_photo->loaded()) { if (!_photo->loaded()) {
subscribe(Auth().downloaderTaskFinished(), [this] { update(); }); subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
_photo->load(); _photo->load(Data::FileOrigin());
} }
} }
} }
@ -730,15 +736,31 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
Painter p(this); Painter p(this);
if (_photo) { if (_photo) {
p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize)); p.drawPixmap(
(width() - st::confirmInvitePhotoSize) / 2,
st::confirmInvitePhotoTop,
_photo->pixCircled(
Data::FileOrigin(),
st::confirmInvitePhotoSize,
st::confirmInvitePhotoSize));
} else { } else {
_photoEmpty->paint(p, (width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, width(), st::confirmInvitePhotoSize); _photoEmpty->paint(
p,
(width() - st::confirmInvitePhotoSize) / 2,
st::confirmInvitePhotoTop,
width(),
st::confirmInvitePhotoSize);
} }
int sumWidth = _participants.size() * _userWidth; int sumWidth = _participants.size() * _userWidth;
int left = (width() - sumWidth) / 2; int left = (width() - sumWidth) / 2;
for_const (auto user, _participants) { for_const (auto user, _participants) {
user->paintUserpicLeft(p, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, st::confirmInviteUserPhotoTop, width(), st::confirmInviteUserPhotoSize); user->paintUserpicLeft(
p,
left + (_userWidth - st::confirmInviteUserPhotoSize) / 2,
st::confirmInviteUserPhotoTop,
width(),
st::confirmInviteUserPhotoSize);
left += _userWidth; left += _userWidth;
} }
} }

View file

@ -79,7 +79,7 @@ EditCaptionBox::EditCaptionBox(
| Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomLeft
| Images::Option::RoundedBottomRight; | Images::Option::RoundedBottomRight;
_thumb = Images::pixmap( _thumb = Images::pixmap(
image->pix().toImage(), image->pix(_msgId).toImage(),
_thumbw * cIntRetinaFactor(), _thumbw * cIntRetinaFactor(),
0, 0,
options, options,
@ -129,6 +129,7 @@ EditCaptionBox::EditCaptionBox(
const auto options = Images::Option::Smooth const auto options = Images::Option::Smooth
| Images::Option::Blurred; | Images::Option::Blurred;
_thumb = image->pixNoCache( _thumb = image->pixNoCache(
_msgId,
maxW * cIntRetinaFactor(), maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(), maxH * cIntRetinaFactor(),
options, options,
@ -142,6 +143,7 @@ EditCaptionBox::EditCaptionBox(
_thumbnailImage = image; _thumbnailImage = image;
_refreshThumbnail = [=] { _refreshThumbnail = [=] {
_thumb = image->pixNoCache( _thumb = image->pixNoCache(
_msgId,
maxW * cIntRetinaFactor(), maxW * cIntRetinaFactor(),
maxH * cIntRetinaFactor(), maxH * cIntRetinaFactor(),
Images::Option::Smooth, Images::Option::Smooth,

View file

@ -281,7 +281,9 @@ void StickerSetBox::Inner::mouseMoveEvent(QMouseEvent *e) {
int index = stickerFromGlobalPos(e->globalPos()); int index = stickerFromGlobalPos(e->globalPos());
if (index >= 0 && index < _pack.size() && index != _previewShown) { if (index >= 0 && index < _pack.size() && index != _previewShown) {
_previewShown = index; _previewShown = index;
Ui::showMediaPreview(_pack.at(_previewShown)); Ui::showMediaPreview(
Data::FileOriginStickerSet(_setId, _setAccess),
_pack[_previewShown]);
} }
} }
} }
@ -338,7 +340,9 @@ void StickerSetBox::Inner::onPreview() {
int index = stickerFromGlobalPos(QCursor::pos()); int index = stickerFromGlobalPos(QCursor::pos());
if (index >= 0 && index < _pack.size()) { if (index >= 0 && index < _pack.size()) {
_previewShown = index; _previewShown = index;
Ui::showMediaPreview(_pack.at(_previewShown)); Ui::showMediaPreview(
Data::FileOriginStickerSet(_setId, _setAccess),
_pack[_previewShown]);
} }
} }
@ -381,19 +385,7 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
p.setOpacity(1); p.setOpacity(1);
} }
const auto goodThumb = doc->hasGoodStickerThumb(); doc->checkStickerThumb();
if (goodThumb) {
doc->thumb->load();
} else {
if (doc->status == FileReady) {
doc->automaticLoad(0);
}
if (doc->sticker()->img->isNull() && doc->loaded(DocumentData::FilePathResolveChecked)) {
doc->sticker()->img = doc->data().isEmpty()
? ImagePtr(doc->filepath())
: ImagePtr(doc->data());
}
}
float64 coef = qMin((st::stickersSize.width() - st::buttonRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::buttonRadius * 2) / float64(doc->dimensions.height())); float64 coef = qMin((st::stickersSize.width() - st::buttonRadius * 2) / float64(doc->dimensions.width()), (st::stickersSize.height() - st::buttonRadius * 2) / float64(doc->dimensions.height()));
if (coef > 1) coef = 1; if (coef > 1) coef = 1;
@ -401,10 +393,11 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
if (w < 1) w = 1; if (w < 1) w = 1;
if (h < 1) h = 1; if (h < 1) h = 1;
QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2); QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2);
if (goodThumb) { if (const auto image = doc->getStickerThumb()) {
p.drawPixmapLeft(ppos, width(), doc->thumb->pix(w, h)); p.drawPixmapLeft(
} else if (!doc->sticker()->img->isNull()) { ppos,
p.drawPixmapLeft(ppos, width(), doc->sticker()->img->pix(w, h)); width(),
image->pix(doc->stickerSetOrigin(), w, h));
} }
} }
} }

View file

@ -568,7 +568,22 @@ void StickersBox::setInnerFocus() {
StickersBox::~StickersBox() = default; StickersBox::~StickersBox() = default;
StickersBox::Inner::Row::Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh) : id(id) StickersBox::Inner::Row::Row(
uint64 id,
uint64 accessHash,
DocumentData *sticker,
int32 count,
const QString &title,
int titleWidth,
bool installed,
bool official,
bool unread,
bool archived,
bool removed,
int32 pixw,
int32 pixh)
: id(id)
, accessHash(accessHash)
, sticker(sticker) , sticker(sticker)
, count(count) , count(count)
, title(title) , title(title)
@ -782,8 +797,11 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index, TimeMs ms) {
} }
if (set->sticker) { if (set->sticker) {
set->sticker->thumb->load(); const auto origin = Data::FileOriginStickerSet(
auto pix = set->sticker->thumb->pix(set->pixw, set->pixh); set->id,
set->accessHash);
set->sticker->thumb->load(origin);
auto pix = set->sticker->thumb->pix(origin, set->pixw, set->pixh);
p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - set->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2, width(), pix); p.drawPixmapLeft(stickerx + (st::contactsPhotoSize - set->pixw) / 2, st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2, width(), pix);
} }
@ -1342,7 +1360,20 @@ void StickersBox::Inner::rebuildMegagroupSet() {
_megagroupSetField->setText(it->shortName); _megagroupSetField->setText(it->shortName);
_megagroupSetField->finishAnimating(); _megagroupSetField->finishAnimating();
} }
_megagroupSelectedSet = std::make_unique<Row>(it->id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh); _megagroupSelectedSet = std::make_unique<Row>(
it->id,
it->access,
sticker,
count,
title,
titleWidth,
installed,
official,
unread,
archived,
removed,
pixw,
pixh);
_itemsTop += st::lineWidth + _rowHeight; _itemsTop += st::lineWidth + _rowHeight;
if (!_megagroupSelectedRemove) { if (!_megagroupSelectedRemove) {
@ -1512,7 +1543,20 @@ void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameW
QString title = fillSetTitle(set, maxNameWidth, &titleWidth); QString title = fillSetTitle(set, maxNameWidth, &titleWidth);
int count = fillSetCount(set); int count = fillSetCount(set);
_rows.push_back(std::make_unique<Row>(set.id, sticker, count, title, titleWidth, installed, official, unread, archived, removed, pixw, pixh)); _rows.push_back(std::make_unique<Row>(
set.id,
set.access,
sticker,
count,
title,
titleWidth,
installed,
official,
unread,
archived,
removed,
pixw,
pixh));
_animStartTimes.push_back(0); _animStartTimes.push_back(0);
} }

View file

@ -190,13 +190,27 @@ public slots:
private: private:
struct Row { struct Row {
Row(uint64 id, DocumentData *sticker, int32 count, const QString &title, int titleWidth, bool installed, bool official, bool unread, bool archived, bool removed, int32 pixw, int32 pixh); Row(
uint64 id,
uint64 accessHash,
DocumentData *sticker,
int32 count,
const QString &title,
int titleWidth,
bool installed,
bool official,
bool unread,
bool archived,
bool removed,
int32 pixw,
int32 pixh);
bool isRecentSet() const { bool isRecentSet() const {
return (id == Stickers::CloudRecentSetId); return (id == Stickers::CloudRecentSetId);
} }
~Row(); ~Row();
uint64 id = 0; uint64 id = 0;
uint64 accessHash = 0;
DocumentData *sticker = nullptr; DocumentData *sticker = nullptr;
int32 count = 0; int32 count = 0;
QString title; QString title;

View file

@ -503,7 +503,7 @@ void Panel::processUserPhoto() {
? Auth().data().photo(_user->userpicPhotoId()).get() ? Auth().data().photo(_user->userpicPhotoId()).get()
: nullptr; : nullptr;
if (isGoodUserPhoto(photo)) { if (isGoodUserPhoto(photo)) {
photo->full->load(true); photo->full->load(_user->userpicPhotoOrigin(), true);
} else if (_user->userpicPhotoUnknown() || (photo && !photo->date)) { } else if (_user->userpicPhotoUnknown() || (photo && !photo->date)) {
Auth().api().requestFullPeer(_user); Auth().api().requestFullPeer(_user);
} }
@ -540,7 +540,13 @@ void Panel::createUserpicCache(ImagePtr image) {
height = qMax((height * size) / width, 1); height = qMax((height * size) / width, 1);
width = size; width = size;
} }
_userPhoto = image->pixNoCache(width, height, options, st::callWidth, st::callWidth); _userPhoto = image->pixNoCache(
_user->userpicPhotoOrigin(),
width,
height,
options,
st::callWidth,
st::callWidth);
if (cRetina()) _userPhoto.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _userPhoto.setDevicePixelRatio(cRetinaFactor());
} else { } else {
auto filled = QImage(QSize(st::callWidth, st::callWidth) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto filled = QImage(QSize(st::callWidth, st::callWidth) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);

View file

@ -551,8 +551,8 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
int32 index = row * _stickersPerRow + col; int32 index = row * _stickersPerRow + col;
if (index >= _srows->size()) break; if (index >= _srows->size()) break;
DocumentData *sticker = _srows->at(index); const auto document = _srows->at(index);
if (!sticker->sticker()) continue; if (!document->sticker()) continue;
QPoint pos(st::stickerPanPadding + col * st::stickerPanSize.width(), st::stickerPanPadding + row * st::stickerPanSize.height()); QPoint pos(st::stickerPanPadding + col * st::stickerPanSize.width(), st::stickerPanPadding + row * st::stickerPanSize.height());
if (_sel == index) { if (_sel == index) {
@ -561,23 +561,16 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners); App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
} }
const auto goodThumb = sticker->hasGoodStickerThumb(); document->checkStickerThumb();
if (goodThumb) {
sticker->thumb->load();
} else {
sticker->checkSticker();
}
float64 coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height())); float64 coef = qMin((st::stickerPanSize.width() - st::buttonRadius * 2) / float64(document->dimensions.width()), (st::stickerPanSize.height() - st::buttonRadius * 2) / float64(document->dimensions.height()));
if (coef > 1) coef = 1; if (coef > 1) coef = 1;
int32 w = qRound(coef * sticker->dimensions.width()), h = qRound(coef * sticker->dimensions.height()); int32 w = qRound(coef * document->dimensions.width()), h = qRound(coef * document->dimensions.height());
if (w < 1) w = 1; if (w < 1) w = 1;
if (h < 1) h = 1; if (h < 1) h = 1;
QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2); QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
if (goodThumb) { if (const auto image = document->getStickerThumb()) {
p.drawPixmapLeft(ppos, width(), sticker->thumb->pix(w, h)); p.drawPixmapLeft(ppos, width(), image->pix(document->stickerSetOrigin(), w, h));
} else if (!sticker->sticker()->img->isNull()) {
p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pix(w, h));
} }
} }
} }
@ -901,7 +894,9 @@ void FieldAutocompleteInner::onUpdateSelected(bool force) {
if (_down >= 0 && _sel >= 0 && _down != _sel) { if (_down >= 0 && _sel >= 0 && _down != _sel) {
_down = _sel; _down = _sel;
if (_down >= 0 && _down < _srows->size()) { if (_down >= 0 && _down < _srows->size()) {
Ui::showMediaPreview(_srows->at(_down)); Ui::showMediaPreview(
(*_srows)[_down]->stickerSetOrigin(),
(*_srows)[_down]);
} }
} }
} }
@ -917,7 +912,9 @@ void FieldAutocompleteInner::onParentGeometryChanged() {
void FieldAutocompleteInner::onPreview() { void FieldAutocompleteInner::onPreview() {
if (_down >= 0 && _down < _srows->size()) { if (_down >= 0 && _down < _srows->size()) {
Ui::showMediaPreview(_srows->at(_down)); Ui::showMediaPreview(
(*_srows)[_down]->stickerSetOrigin(),
(*_srows)[_down]);
_previewShown = true; _previewShown = true;
} }
} }

View file

@ -343,16 +343,21 @@ void GifsListWidget::selectInlineResult(int row, int column) {
if (photo->medium->loaded() || photo->thumb->loaded()) { if (photo->medium->loaded() || photo->thumb->loaded()) {
emit selected(photo); emit selected(photo);
} else if (!photo->medium->loading()) { } else if (!photo->medium->loading()) {
photo->thumb->loadEvenCancelled(); photo->thumb->loadEvenCancelled(Data::FileOrigin());
photo->medium->loadEvenCancelled(); photo->medium->loadEvenCancelled(Data::FileOrigin());
} }
} else if (auto document = item->getDocument()) { } else if (const auto document = item->getDocument()) {
if (document->loaded()) { if (document->loaded()) {
emit selected(document); emit selected(document);
} else if (document->loading()) { } else if (document->loading()) {
document->cancel(); document->cancel();
} else { } else {
DocumentOpenClickHandler::doOpen(document, nullptr, ActionOnLoadNone);
DocumentOpenClickHandler::Open(
document->stickerOrGifOrigin(),
document,
nullptr,
ActionOnLoadNone);
} }
} else if (auto inlineResult = item->getResult()) { } else if (auto inlineResult = item->getResult()) {
if (inlineResult->onChoose(item)) { if (inlineResult->onChoose(item)) {
@ -764,6 +769,12 @@ bool GifsListWidget::inlineItemVisible(const InlineBots::Layout::ItemBase *layou
return (top < getVisibleBottom()) && (top + _rows[row].items[col]->height() > getVisibleTop()); return (top < getVisibleBottom()) && (top + _rows[row].items[col]->height() > getVisibleTop());
} }
Data::FileOrigin GifsListWidget::inlineItemFileOrigin() {
return _inlineQuery.isEmpty()
? Data::FileOriginSavedGifs()
: Data::FileOrigin();
}
void GifsListWidget::afterShown() { void GifsListWidget::afterShown() {
if (_footer) { if (_footer) {
_footer->stealFocus(); _footer->stealFocus();
@ -948,10 +959,14 @@ void GifsListWidget::updateSelected() {
_pressed = _selected; _pressed = _selected;
if (row >= 0 && col >= 0) { if (row >= 0 && col >= 0) {
auto layout = _rows[row].items[col]; auto layout = _rows[row].items[col];
if (auto previewDocument = layout->getPreviewDocument()) { if (const auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(previewDocument); Ui::showMediaPreview(
} else if (auto previewPhoto = layout->getPreviewPhoto()) { Data::FileOriginSavedGifs(),
Ui::showMediaPreview(previewPhoto); previewDocument);
} else if (const auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(
Data::FileOrigin(),
previewPhoto);
} }
} }
} }
@ -966,11 +981,15 @@ void GifsListWidget::onPreview() {
int row = _pressed / MatrixRowShift, col = _pressed % MatrixRowShift; int row = _pressed / MatrixRowShift, col = _pressed % MatrixRowShift;
if (row < _rows.size() && col < _rows[row].items.size()) { if (row < _rows.size() && col < _rows[row].items.size()) {
auto layout = _rows[row].items[col]; auto layout = _rows[row].items[col];
if (auto previewDocument = layout->getPreviewDocument()) { if (const auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(previewDocument); Ui::showMediaPreview(
Data::FileOriginSavedGifs(),
previewDocument);
_previewShown = true; _previewShown = true;
} else if (auto previewPhoto = layout->getPreviewPhoto()) { } else if (const auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(previewPhoto); Ui::showMediaPreview(
Data::FileOrigin(),
previewPhoto);
_previewShown = true; _previewShown = true;
} }
} }

View file

@ -45,6 +45,7 @@ public:
void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) override; void inlineItemLayoutChanged(const InlineBots::Layout::ItemBase *layout) override;
void inlineItemRepaint(const InlineBots::Layout::ItemBase *layout) override; void inlineItemRepaint(const InlineBots::Layout::ItemBase *layout) override;
bool inlineItemVisible(const InlineBots::Layout::ItemBase *layout) override; bool inlineItemVisible(const InlineBots::Layout::ItemBase *layout) override;
Data::FileOrigin inlineItemFileOrigin() override;
void afterShown() override; void afterShown() override;
void beforeHiding() override; void beforeHiding() override;

View file

@ -258,7 +258,7 @@ void StickersListWidget::Footer::enumerateVisibleIcons(Callback callback) {
void StickersListWidget::Footer::preloadImages() { void StickersListWidget::Footer::preloadImages() {
enumerateVisibleIcons([](const StickerIcon &icon, int x) { enumerateVisibleIcons([](const StickerIcon &icon, int x) {
if (auto sticker = icon.sticker) { if (auto sticker = icon.sticker) {
sticker->thumb->load(); sticker->thumb->load(sticker->stickerSetOrigin());
} }
}); });
} }
@ -628,8 +628,9 @@ void StickersListWidget::Footer::paintSetIcon(
const StickerIcon &icon, const StickerIcon &icon,
int x) const { int x) const {
if (icon.sticker) { if (icon.sticker) {
icon.sticker->thumb->load(); const auto origin = icon.sticker->stickerSetOrigin();
auto pix = icon.sticker->thumb->pix(icon.pixw, icon.pixh); icon.sticker->thumb->load(origin);
auto pix = icon.sticker->thumb->pix(origin, icon.pixw, icon.pixh);
p.drawPixmapLeft(x + (st::stickerIconWidth - icon.pixw) / 2, _iconsTop + (st::emojiFooterHeight - icon.pixh) / 2, width(), pix); p.drawPixmapLeft(x + (st::stickerIconWidth - icon.pixw) / 2, _iconsTop + (st::emojiFooterHeight - icon.pixh) / 2, width(), pix);
} else if (icon.megagroup) { } else if (icon.megagroup) {
@ -1306,8 +1307,8 @@ void StickersListWidget::paintMegagroupEmptySet(Painter &p, int y, bool buttonSe
} }
void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bool selected, bool deleteSelected) { void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bool selected, bool deleteSelected) {
auto sticker = set.pack[index]; auto document = set.pack[index];
if (!sticker->sticker()) return; if (!document->sticker()) return;
int row = (index / _columnCount), col = (index % _columnCount); int row = (index / _columnCount), col = (index % _columnCount);
@ -1318,30 +1319,26 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bo
App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners); App::roundRect(p, QRect(tl, _singleSize), st::emojiPanHover, StickerHoverCorners);
} }
const auto goodThumb = sticker->hasGoodStickerThumb(); document->checkStickerThumb();
if (goodThumb) {
sticker->thumb->load();
} else {
sticker->checkSticker();
}
auto coef = qMin((_singleSize.width() - st::buttonRadius * 2) / float64(sticker->dimensions.width()), (_singleSize.height() - st::buttonRadius * 2) / float64(sticker->dimensions.height())); auto coef = qMin((_singleSize.width() - st::buttonRadius * 2) / float64(document->dimensions.width()), (_singleSize.height() - st::buttonRadius * 2) / float64(document->dimensions.height()));
if (coef > 1) coef = 1; if (coef > 1) coef = 1;
auto w = qMax(qRound(coef * sticker->dimensions.width()), 1); auto w = qMax(qRound(coef * document->dimensions.width()), 1);
auto h = qMax(qRound(coef * sticker->dimensions.height()), 1); auto h = qMax(qRound(coef * document->dimensions.height()), 1);
auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2); auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2);
auto paintImage = [&](ImagePtr image) { if (const auto image = document->getStickerThumb()) {
if (image->loaded()) { if (image->loaded()) {
p.drawPixmapLeft( p.drawPixmapLeft(
ppos, ppos,
width(), width(),
image->pixSingle(w, h, w, h, ImageRoundRadius::None)); image->pixSingle(
document->stickerSetOrigin(),
w,
h,
w,
h,
ImageRoundRadius::None));
} }
};
if (goodThumb) {
paintImage(sticker->thumb);
} else if (!sticker->sticker()->img->isNull()) {
paintImage(sticker->sticker()->img);
} }
if (selected && stickerHasDeleteButton(set, index)) { if (selected && stickerHasDeleteButton(set, index)) {
@ -1764,15 +1761,10 @@ void StickersListWidget::preloadImages() {
for (int j = 0; j != count; ++j) { for (int j = 0; j != count; ++j) {
if (++k > _columnCount * (_columnCount + 1)) break; if (++k > _columnCount * (_columnCount + 1)) break;
auto sticker = sets[i].pack.at(j); const auto document = sets[i].pack[j];
if (!sticker || !sticker->sticker()) continue; if (!document || !document->sticker()) continue;
const auto goodThumb = sticker->hasGoodStickerThumb(); document->checkStickerThumb();
if (goodThumb) {
sticker->thumb->load();
} else {
sticker->automaticLoad(0);
}
} }
if (k > _columnCount * (_columnCount + 1)) break; if (k > _columnCount * (_columnCount + 1)) break;
} }
@ -2162,7 +2154,9 @@ void StickersListWidget::setSelected(OverState newSelected) {
Assert(sticker->section >= 0 && sticker->section < sets.size()); Assert(sticker->section >= 0 && sticker->section < sets.size());
auto &set = sets[sticker->section]; auto &set = sets[sticker->section];
Assert(sticker->index >= 0 && sticker->index < set.pack.size()); Assert(sticker->index >= 0 && sticker->index < set.pack.size());
Ui::showMediaPreview(set.pack[sticker->index]); Ui::showMediaPreview(
set.pack[sticker->index]->stickerSetOrigin(),
set.pack[sticker->index]);
} }
} }
} }
@ -2178,7 +2172,9 @@ void StickersListWidget::onPreview() {
Assert(sticker->section >= 0 && sticker->section < sets.size()); Assert(sticker->section >= 0 && sticker->section < sets.size());
auto &set = sets[sticker->section]; auto &set = sets[sticker->section];
Assert(sticker->index >= 0 && sticker->index < set.pack.size()); Assert(sticker->index >= 0 && sticker->index < set.pack.size());
Ui::showMediaPreview(set.pack[sticker->index]); Ui::showMediaPreview(
set.pack[sticker->index]->stickerSetOrigin(),
set.pack[sticker->index]);
_previewShown = true; _previewShown = true;
} }
} }

View file

@ -1467,7 +1467,6 @@ auto MtpChecker::parseFile(const MTPmessages_Messages &result) const
const auto location = MTP_inputDocumentFileLocation( const auto location = MTP_inputDocumentFileLocation(
fields.vid, fields.vid,
fields.vaccess_hash, fields.vaccess_hash,
fields.vversion,
fields.vfile_reference); fields.vfile_reference);
return ParsedFile { name, size, fields.vdc_id.v, location }; return ParsedFile { name, size, fields.vdc_id.v, location };
} }

View file

@ -232,7 +232,8 @@ QString documentSaveFilename(const DocumentData *data, bool forceSavingAs = fals
return FileNameForSave(caption, filter, prefix, name, forceSavingAs, dir); return FileNameForSave(caption, filter, prefix, name, forceSavingAs, dir);
} }
void DocumentOpenClickHandler::doOpen( void DocumentOpenClickHandler::Open(
Data::FileOrigin origin,
not_null<DocumentData*> data, not_null<DocumentData*> data,
HistoryItem *context, HistoryItem *context,
ActionOnLoad action) { ActionOnLoad action) {
@ -334,7 +335,7 @@ void DocumentOpenClickHandler::doOpen(
if (filename.isEmpty()) return; if (filename.isEmpty()) return;
} }
data->save(filename, action, msgId); data->save(origin, filename, action, msgId);
} }
void DocumentOpenClickHandler::onClickImpl() const { void DocumentOpenClickHandler::onClickImpl() const {
@ -342,14 +343,15 @@ void DocumentOpenClickHandler::onClickImpl() const {
const auto action = data->isVoiceMessage() const auto action = data->isVoiceMessage()
? ActionOnLoadNone ? ActionOnLoadNone
: ActionOnLoadOpen; : ActionOnLoadOpen;
doOpen(data, getActionItem(), action); Open(context(), data, getActionItem(), action);
} }
void GifOpenClickHandler::onClickImpl() const { void GifOpenClickHandler::onClickImpl() const {
doOpen(document(), getActionItem(), ActionOnLoadPlayInline); Open(context(), document(), getActionItem(), ActionOnLoadPlayInline);
} }
void DocumentSaveClickHandler::doSave( void DocumentSaveClickHandler::Save(
Data::FileOrigin origin,
not_null<DocumentData*> data, not_null<DocumentData*> data,
bool forceSavingAs) { bool forceSavingAs) {
if (!data->date) return; if (!data->date) return;
@ -365,13 +367,13 @@ void DocumentSaveClickHandler::doSave(
auto filename = filepath.isEmpty() ? QString() : fileinfo.fileName(); auto filename = filepath.isEmpty() ? QString() : fileinfo.fileName();
auto newfname = documentSaveFilename(data, forceSavingAs, filename, filedir); auto newfname = documentSaveFilename(data, forceSavingAs, filename, filedir);
if (!newfname.isEmpty()) { if (!newfname.isEmpty()) {
data->save(newfname, ActionOnLoadNone, FullMsgId()); data->save(origin, newfname, ActionOnLoadNone, FullMsgId());
} }
} }
} }
void DocumentSaveClickHandler::onClickImpl() const { void DocumentSaveClickHandler::onClickImpl() const {
doSave(document()); Save(context(), document());
} }
void DocumentCancelClickHandler::onClickImpl() const { void DocumentCancelClickHandler::onClickImpl() const {
@ -387,6 +389,15 @@ void DocumentCancelClickHandler::onClickImpl() const {
} }
} }
Data::FileOrigin StickerData::setOrigin() const {
return set.match([&](const MTPDinputStickerSetID &data) {
return Data::FileOrigin(
Data::FileOriginStickerSet(data.vid.v, data.vaccess_hash.v));
}, [&](const auto &) {
return Data::FileOrigin();
});
}
VoiceData::~VoiceData() { VoiceData::~VoiceData() {
if (!waveform.isEmpty() if (!waveform.isEmpty()
&& waveform[0] == -1 && waveform[0] == -1
@ -514,12 +525,14 @@ void DocumentData::forget() {
_data.clear(); _data.clear();
} }
void DocumentData::automaticLoad(const HistoryItem *item) { void DocumentData::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (loaded() || status != FileReady) return; if (loaded() || status != FileReady) return;
if (saveToCache() && _loader != CancelledMtpFileLoader) { if (saveToCache() && _loader != CancelledMtpFileLoader) {
if (type == StickerDocument) { if (type == StickerDocument) {
save(QString(), _actionOnLoad, _actionOnLoadMsgId); save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId);
} else if (isAnimation()) { } else if (isAnimation()) {
bool loadFromCloud = false; bool loadFromCloud = false;
if (item) { if (item) {
@ -531,7 +544,7 @@ void DocumentData::automaticLoad(const HistoryItem *item) {
} else { // if load at least anywhere } else { // if load at least anywhere
loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate) || !(cAutoDownloadGif() & dbiadNoGroups); loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate) || !(cAutoDownloadGif() & dbiadNoGroups);
} }
save(QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true); save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
} else if (isVoiceMessage()) { } else if (isVoiceMessage()) {
if (item) { if (item) {
bool loadFromCloud = false; bool loadFromCloud = false;
@ -540,7 +553,7 @@ void DocumentData::automaticLoad(const HistoryItem *item) {
} else { } else {
loadFromCloud = !(cAutoDownloadAudio() & dbiadNoGroups); loadFromCloud = !(cAutoDownloadAudio() & dbiadNoGroups);
} }
save(QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true); save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
} }
} }
} }
@ -706,6 +719,7 @@ bool DocumentData::waitingForAlbum() const {
} }
void DocumentData::save( void DocumentData::save(
Data::FileOrigin origin,
const QString &toFile, const QString &toFile,
ActionOnLoad action, ActionOnLoad action,
const FullMsgId &actionMsgId, const FullMsgId &actionMsgId,
@ -768,8 +782,8 @@ void DocumentData::save(
_dc, _dc,
id, id,
_access, _access,
_version,
_fileReference, _fileReference,
origin,
locationType(), locationType(),
toFile, toFile,
size, size,
@ -924,7 +938,7 @@ bool DocumentData::isStickerSetInstalled() const {
return false; return false;
} }
ImagePtr DocumentData::makeReplyPreview() { ImagePtr DocumentData::makeReplyPreview(Data::FileOrigin origin) {
if (replyPreview->isNull() && !thumb->isNull()) { if (replyPreview->isNull() && !thumb->isNull()) {
if (thumb->loaded()) { if (thumb->loaded()) {
int w = thumb->width(), h = thumb->height(); int w = thumb->width(), h = thumb->height();
@ -934,10 +948,10 @@ ImagePtr DocumentData::makeReplyPreview() {
thumbSize *= cIntRetinaFactor(); thumbSize *= cIntRetinaFactor();
auto options = Images::Option::Smooth | (isVideoMessage() ? Images::Option::Circled : Images::Option::None) | Images::Option::TransparentBackground; auto options = Images::Option::Smooth | (isVideoMessage() ? Images::Option::Circled : Images::Option::None) | Images::Option::TransparentBackground;
auto outerSize = st::msgReplyBarSize.height(); auto outerSize = st::msgReplyBarSize.height();
auto image = thumb->pixNoCache(thumbSize.width(), thumbSize.height(), options, outerSize, outerSize); auto image = thumb->pixNoCache(origin, thumbSize.width(), thumbSize.height(), options, outerSize, outerSize);
replyPreview = ImagePtr(image, "PNG"); replyPreview = ImagePtr(image, "PNG");
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
return replyPreview; return replyPreview;
@ -953,10 +967,10 @@ void DocumentData::checkSticker() {
const auto data = sticker(); const auto data = sticker();
if (!data) return; if (!data) return;
automaticLoad(nullptr); automaticLoad(stickerSetOrigin(), nullptr);
if (data->img->isNull() && loaded()) { if (data->img->isNull() && loaded()) {
if (_data.isEmpty()) { if (_data.isEmpty()) {
const FileLocation &loc(location(true)); const auto &loc = location(true);
if (loc.accessEnable()) { if (loc.accessEnable()) {
data->img = ImagePtr(loc.name()); data->img = ImagePtr(loc.name());
loc.accessDisable(); loc.accessDisable();
@ -967,6 +981,38 @@ void DocumentData::checkSticker() {
} }
} }
void DocumentData::checkStickerThumb() {
if (hasGoodStickerThumb()) {
thumb->load(stickerSetOrigin());
} else {
checkSticker();
}
}
ImagePtr DocumentData::getStickerThumb() {
if (hasGoodStickerThumb()) {
return thumb;
} else if (const auto data = sticker()) {
return data->img;
}
return ImagePtr();
}
Data::FileOrigin DocumentData::stickerSetOrigin() const {
if (const auto data = sticker()) {
return data->setOrigin();
}
return Data::FileOrigin();
}
Data::FileOrigin DocumentData::stickerOrGifOrigin() const {
return (sticker()
? stickerSetOrigin()
: isGifv()
? Data::FileOriginSavedGifs()
: Data::FileOrigin());
}
SongData *DocumentData::song() { SongData *DocumentData::song() {
return isSong() return isSong()
? static_cast<SongData*>(_additional.get()) ? static_cast<SongData*>(_additional.get())
@ -1026,7 +1072,7 @@ void DocumentData::setMimeString(const QString &mime) {
} }
MediaKey DocumentData::mediaKey() const { MediaKey DocumentData::mediaKey() const {
return ::mediaKey(locationType(), _dc, id, _version); return ::mediaKey(locationType(), _dc, id);
} }
QString DocumentData::composeNameString() const { QString DocumentData::composeNameString() const {
@ -1120,20 +1166,6 @@ bool DocumentData::hasGoodStickerThumb() const {
&& ((thumb->width() >= 128) || (thumb->height() >= 128)); && ((thumb->width() >= 128) || (thumb->height() >= 128));
} }
bool DocumentData::setRemoteVersion(int32 version) {
if (_version == version) {
return false;
}
_version = version;
_location = FileLocation();
_data = QByteArray();
status = FileReady;
if (loading()) {
destroyLoaderDelayed();
}
return true;
}
void DocumentData::setRemoteLocation( void DocumentData::setRemoteLocation(
int32 dc, int32 dc,
uint64 access, uint64 access,

View file

@ -10,23 +10,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_types.h" #include "data/data_types.h"
class AuthSession; class AuthSession;
class mtpFileLoader;
inline uint64 mediaMix32To64(int32 a, int32 b) { inline uint64 mediaMix32To64(int32 a, int32 b) {
return (uint64(*reinterpret_cast<uint32*>(&a)) << 32) return (uint64(*reinterpret_cast<uint32*>(&a)) << 32)
| uint64(*reinterpret_cast<uint32*>(&b)); | uint64(*reinterpret_cast<uint32*>(&b));
} }
// Old method, should not be used anymore. // version field removed from document.
//inline MediaKey mediaKey(LocationType type, int32 dc, const uint64 &id) { inline MediaKey mediaKey(LocationType type, int32 dc, const uint64 &id) {
// return MediaKey(mediaMix32To64(type, dc), id); return MediaKey(mediaMix32To64(type, dc), id);
//}
// New method when version was introduced, type is not relevant anymore (all files are Documents).
inline MediaKey mediaKey(
LocationType type,
int32 dc,
const uint64 &id,
int32 version) {
return (version > 0) ? MediaKey(mediaMix32To64(version, dc), id) : MediaKey(mediaMix32To64(type, dc), id);
} }
inline StorageKey mediaKey(const MTPDfileLocation &location) { inline StorageKey mediaKey(const MTPDfileLocation &location) {
@ -42,11 +35,12 @@ struct DocumentAdditionalData {
}; };
struct StickerData : public DocumentAdditionalData { struct StickerData : public DocumentAdditionalData {
Data::FileOrigin setOrigin() const;
ImagePtr img; ImagePtr img;
QString alt; QString alt;
MTPInputStickerSet set = MTP_inputStickerSetEmpty(); MTPInputStickerSet set = MTP_inputStickerSetEmpty();
StorageImageLocation loc; // doc thumb location StorageImageLocation loc; // doc thumb location
}; };
struct SongData : public DocumentAdditionalData { struct SongData : public DocumentAdditionalData {
@ -78,7 +72,9 @@ public:
void setattributes( void setattributes(
const QVector<MTPDocumentAttribute> &attributes); const QVector<MTPDocumentAttribute> &attributes);
void automaticLoad(const HistoryItem *item); // auto load sticker or video void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item); // auto load sticker or video
void automaticLoadSettingsChanged(); void automaticLoadSettingsChanged();
enum FilePathResolveType { enum FilePathResolveType {
@ -93,6 +89,7 @@ public:
QString loadingFilePath() const; QString loadingFilePath() const;
bool displayLoading() const; bool displayLoading() const;
void save( void save(
Data::FileOrigin origin,
const QString &toFile, const QString &toFile,
ActionOnLoad action = ActionOnLoadNone, ActionOnLoad action = ActionOnLoadNone,
const FullMsgId &actionMsgId = FullMsgId(), const FullMsgId &actionMsgId = FullMsgId(),
@ -119,10 +116,14 @@ public:
void performActionOnLoad(); void performActionOnLoad();
void forget(); void forget();
ImagePtr makeReplyPreview(); ImagePtr makeReplyPreview(Data::FileOrigin origin);
StickerData *sticker() const; StickerData *sticker() const;
void checkSticker(); void checkSticker();
void checkStickerThumb();
ImagePtr getStickerThumb();
Data::FileOrigin stickerSetOrigin() const;
Data::FileOrigin stickerOrGifOrigin() const;
bool isStickerSetInstalled() const; bool isStickerSetInstalled() const;
SongData *song(); SongData *song();
const SongData *song() const; const SongData *song() const;
@ -147,7 +148,6 @@ public:
bool hasGoodStickerThumb() const; bool hasGoodStickerThumb() const;
bool setRemoteVersion(int32 version); // Returns true if version has changed.
void setRemoteLocation( void setRemoteLocation(
int32 dc, int32 dc,
uint64 access, uint64 access,
@ -198,11 +198,10 @@ private:
void destroyLoaderDelayed(mtpFileLoader *newValue = nullptr) const; void destroyLoaderDelayed(mtpFileLoader *newValue = nullptr) const;
// Two types of location: from MTProto by dc+access+version or from web by url // Two types of location: from MTProto by dc+access or from web by url
int32 _dc = 0; int32 _dc = 0;
uint64 _access = 0; uint64 _access = 0;
QByteArray _fileReference; QByteArray _fileReference;
int32 _version = 0;
QString _url; QString _url;
QString _filename; QString _filename;
QString _mimeString; QString _mimeString;
@ -244,7 +243,8 @@ private:
class DocumentSaveClickHandler : public DocumentClickHandler { class DocumentSaveClickHandler : public DocumentClickHandler {
public: public:
using DocumentClickHandler::DocumentClickHandler; using DocumentClickHandler::DocumentClickHandler;
static void doSave( static void Save(
Data::FileOrigin origin,
not_null<DocumentData*> document, not_null<DocumentData*> document,
bool forceSavingAs = false); bool forceSavingAs = false);
@ -256,7 +256,8 @@ protected:
class DocumentOpenClickHandler : public DocumentClickHandler { class DocumentOpenClickHandler : public DocumentClickHandler {
public: public:
using DocumentClickHandler::DocumentClickHandler; using DocumentClickHandler::DocumentClickHandler;
static void doOpen( static void Open(
Data::FileOrigin origin,
not_null<DocumentData*> document, not_null<DocumentData*> document,
HistoryItem *context, HistoryItem *context,
ActionOnLoad action = ActionOnLoadOpen); ActionOnLoad action = ActionOnLoadOpen);

View file

@ -0,0 +1,53 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_types.h"
namespace Data {
using FileOriginMessage = FullMsgId;
struct FileOriginUserPhoto {
FileOriginUserPhoto(UserId userId, PhotoId photoId)
: userId(userId)
, photoId(photoId) {
}
UserId userId = 0;
PhotoId photoId = 0;
};
struct FileOriginPeerPhoto {
explicit FileOriginPeerPhoto(PeerId peerId) : peerId(peerId) {
}
PeerId peerId = 0;
};
struct FileOriginStickerSet {
FileOriginStickerSet(uint64 setId, uint64 accessHash)
: setId(setId)
, accessHash(accessHash) {
}
uint64 setId = 0;
uint64 accessHash = 0;
};
struct FileOriginSavedGifs {
};
using FileOrigin = base::optional_variant<
FileOriginMessage,
FileOriginUserPhoto,
FileOriginPeerPhoto,
FileOriginStickerSet,
FileOriginSavedGifs>;
} // namespace Data

View file

@ -269,7 +269,7 @@ bool MediaPhoto::hasReplyPreview() const {
} }
ImagePtr MediaPhoto::replyPreview() const { ImagePtr MediaPhoto::replyPreview() const {
return _photo->makeReplyPreview(); return _photo->makeReplyPreview(parent()->fullId());
} }
QString MediaPhoto::notificationText() const { QString MediaPhoto::notificationText() const {
@ -470,7 +470,7 @@ bool MediaFile::hasReplyPreview() const {
} }
ImagePtr MediaFile::replyPreview() const { ImagePtr MediaFile::replyPreview() const {
return _document->makeReplyPreview(); return _document->makeReplyPreview(parent()->fullId());
} }
QString MediaFile::chatsListText() const { QString MediaFile::chatsListText() const {
@ -935,9 +935,9 @@ bool MediaWebPage::hasReplyPreview() const {
ImagePtr MediaWebPage::replyPreview() const { ImagePtr MediaWebPage::replyPreview() const {
if (const auto document = _page->document) { if (const auto document = _page->document) {
return document->makeReplyPreview(); return document->makeReplyPreview(parent()->fullId());
} else if (const auto photo = _page->photo) { } else if (const auto photo = _page->photo) {
return photo->makeReplyPreview(); return photo->makeReplyPreview(parent()->fullId());
} }
return ImagePtr(); return ImagePtr();
} }
@ -998,9 +998,9 @@ bool MediaGame::hasReplyPreview() const {
ImagePtr MediaGame::replyPreview() const { ImagePtr MediaGame::replyPreview() const {
if (const auto document = _game->document) { if (const auto document = _game->document) {
return document->makeReplyPreview(); return document->makeReplyPreview(parent()->fullId());
} else if (const auto photo = _game->photo) { } else if (const auto photo = _game->photo) {
return photo->makeReplyPreview(); return photo->makeReplyPreview(parent()->fullId());
} }
return ImagePtr(); return ImagePtr();
} }
@ -1098,7 +1098,7 @@ bool MediaInvoice::hasReplyPreview() const {
ImagePtr MediaInvoice::replyPreview() const { ImagePtr MediaInvoice::replyPreview() const {
if (const auto photo = _invoice.photo) { if (const auto photo = _invoice.photo) {
return photo->makeReplyPreview(); return photo->makeReplyPreview(parent()->fullId());
} }
return ImagePtr(); return ImagePtr();
} }

View file

@ -187,7 +187,7 @@ void PeerData::setUserpicPhoto(const MTPPhoto &data) {
ImagePtr PeerData::currentUserpic() const { ImagePtr PeerData::currentUserpic() const {
if (_userpic) { if (_userpic) {
_userpic->load(); _userpic->load(userpicPhotoOrigin());
if (_userpic->loaded()) { if (_userpic->loaded()) {
if (!useEmptyUserpic()) { if (!useEmptyUserpic()) {
_userpicEmpty = nullptr; _userpicEmpty = nullptr;
@ -200,7 +200,7 @@ ImagePtr PeerData::currentUserpic() const {
void PeerData::paintUserpic(Painter &p, int x, int y, int size) const { void PeerData::paintUserpic(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) { if (auto userpic = currentUserpic()) {
p.drawPixmap(x, y, userpic->pixCircled(size, size)); p.drawPixmap(x, y, userpic->pixCircled(userpicPhotoOrigin(), size, size));
} else { } else {
_userpicEmpty->paint(p, x, y, x + size + x, size); _userpicEmpty->paint(p, x, y, x + size + x, size);
} }
@ -208,7 +208,7 @@ void PeerData::paintUserpic(Painter &p, int x, int y, int size) const {
void PeerData::paintUserpicRounded(Painter &p, int x, int y, int size) const { void PeerData::paintUserpicRounded(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) { if (auto userpic = currentUserpic()) {
p.drawPixmap(x, y, userpic->pixRounded(size, size, ImageRoundRadius::Small)); p.drawPixmap(x, y, userpic->pixRounded(userpicPhotoOrigin(), size, size, ImageRoundRadius::Small));
} else { } else {
_userpicEmpty->paintRounded(p, x, y, x + size + x, size); _userpicEmpty->paintRounded(p, x, y, x + size + x, size);
} }
@ -216,7 +216,7 @@ void PeerData::paintUserpicRounded(Painter &p, int x, int y, int size) const {
void PeerData::paintUserpicSquare(Painter &p, int x, int y, int size) const { void PeerData::paintUserpicSquare(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) { if (auto userpic = currentUserpic()) {
p.drawPixmap(x, y, userpic->pix(size, size)); p.drawPixmap(x, y, userpic->pix(userpicPhotoOrigin(), size, size));
} else { } else {
_userpicEmpty->paintSquare(p, x, y, x + size + x, size); _userpicEmpty->paintSquare(p, x, y, x + size + x, size);
} }
@ -239,7 +239,7 @@ void PeerData::saveUserpicRounded(const QString &path, int size) const {
QPixmap PeerData::genUserpic(int size) const { QPixmap PeerData::genUserpic(int size) const {
if (auto userpic = currentUserpic()) { if (auto userpic = currentUserpic()) {
return userpic->pixCircled(size, size); return userpic->pixCircled(userpicPhotoOrigin(), size, size);
} }
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());
@ -253,7 +253,7 @@ QPixmap PeerData::genUserpic(int size) const {
QPixmap PeerData::genUserpicRounded(int size) const { QPixmap PeerData::genUserpicRounded(int size) const {
if (auto userpic = currentUserpic()) { if (auto userpic = currentUserpic()) {
return userpic->pixRounded(size, size, ImageRoundRadius::Small); return userpic->pixRounded(userpicPhotoOrigin(), size, size, ImageRoundRadius::Small);
} }
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
result.setDevicePixelRatio(cRetinaFactor()); result.setDevicePixelRatio(cRetinaFactor());

View file

@ -166,7 +166,7 @@ public:
int y, int y,
int size) const; int size) const;
void loadUserpic(bool loadFirst = false, bool prior = true) { void loadUserpic(bool loadFirst = false, bool prior = true) {
_userpic->load(loadFirst, prior); _userpic->load(userpicPhotoOrigin(), loadFirst, prior);
} }
bool userpicLoaded() const { bool userpicLoaded() const {
return _userpic->loaded(); return _userpic->loaded();
@ -190,6 +190,11 @@ public:
PhotoId userpicPhotoId() const { PhotoId userpicPhotoId() const {
return userpicPhotoUnknown() ? 0 : _userpicPhotoId; return userpicPhotoUnknown() ? 0 : _userpicPhotoId;
} }
Data::FileOrigin userpicPhotoOrigin() const {
return (isUser() && userpicPhotoId())
? Data::FileOriginUserPhoto(bareId(), userpicPhotoId())
: Data::FileOrigin(Data::FileOriginPeerPhoto(id));
}
int nameVersion = 1; int nameVersion = 1;

View file

@ -33,16 +33,18 @@ PhotoData::PhotoData(
, full(full) { , full(full) {
} }
void PhotoData::automaticLoad(const HistoryItem *item) { void PhotoData::automaticLoad(
full->automaticLoad(item); Data::FileOrigin origin,
const HistoryItem *item) {
full->automaticLoad(origin, item);
} }
void PhotoData::automaticLoadSettingsChanged() { void PhotoData::automaticLoadSettingsChanged() {
full->automaticLoadSettingsChanged(); full->automaticLoadSettingsChanged();
} }
void PhotoData::download() { void PhotoData::download(Data::FileOrigin origin) {
full->loadEvenCancelled(); full->loadEvenCancelled(origin);
Auth().data().notifyPhotoLayoutChanged(this); Auth().data().notifyPhotoLayoutChanged(this);
} }
@ -107,15 +109,15 @@ void PhotoData::forget() {
full->forget(); full->forget();
} }
ImagePtr PhotoData::makeReplyPreview() { ImagePtr PhotoData::makeReplyPreview(Data::FileOrigin origin) {
if (replyPreview->isNull() && !thumb->isNull()) { if (replyPreview->isNull() && !thumb->isNull()) {
if (thumb->loaded()) { if (thumb->loaded()) {
int w = thumb->width(), h = thumb->height(); int w = thumb->width(), h = thumb->height();
if (w <= 0) w = 1; if (w <= 0) w = 1;
if (h <= 0) h = 1; if (h <= 0) h = 1;
replyPreview = ImagePtr(w > h ? thumb->pix(w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : thumb->pix(st::msgReplyBarSize.height()), "PNG"); replyPreview = ImagePtr(w > h ? thumb->pix(origin, w * st::msgReplyBarSize.height() / h, st::msgReplyBarSize.height()) : thumb->pix(origin, st::msgReplyBarSize.height()), "PNG");
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
return replyPreview; return replyPreview;
@ -136,7 +138,7 @@ void PhotoSaveClickHandler::onClickImpl() const {
auto data = photo(); auto data = photo();
if (!data->date) return; if (!data->date) return;
data->download(); data->download(context());
} }
void PhotoCancelClickHandler::onClickImpl() const { void PhotoCancelClickHandler::onClickImpl() const {

View file

@ -21,10 +21,12 @@ public:
const ImagePtr &medium, const ImagePtr &medium,
const ImagePtr &full); const ImagePtr &full);
void automaticLoad(const HistoryItem *item); void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item);
void automaticLoadSettingsChanged(); void automaticLoadSettingsChanged();
void download(); void download(Data::FileOrigin origin);
bool loaded() const; bool loaded() const;
bool loading() const; bool loading() const;
bool displayLoading() const; bool displayLoading() const;
@ -37,7 +39,7 @@ public:
bool waitingForAlbum() const; bool waitingForAlbum() const;
void forget(); void forget();
ImagePtr makeReplyPreview(); ImagePtr makeReplyPreview(Data::FileOrigin origin);
MTPInputPhoto mtpInput() const; MTPInputPhoto mtpInput() const;

View file

@ -57,7 +57,7 @@ void UpdateImage(ImagePtr &old, ImagePtr now) {
} else if (const auto delayed = old->toDelayedStorageImage()) { } else if (const auto delayed = old->toDelayedStorageImage()) {
const auto location = now->location(); const auto location = now->location();
if (!location.isNull()) { if (!location.isNull()) {
delayed->setStorageLocation(location); delayed->setStorageLocation(Data::FileOrigin(), location);
} }
} }
} }
@ -1011,7 +1011,6 @@ not_null<DocumentData*> Session::document(
return document( return document(
fields.vid.v, fields.vid.v,
fields.vaccess_hash.v, fields.vaccess_hash.v,
fields.vversion.v,
fields.vfile_reference.v, fields.vfile_reference.v,
fields.vdate.v, fields.vdate.v,
fields.vattributes.v, fields.vattributes.v,
@ -1028,7 +1027,6 @@ not_null<DocumentData*> Session::document(
not_null<DocumentData*> Session::document( not_null<DocumentData*> Session::document(
DocumentId id, DocumentId id,
const uint64 &access, const uint64 &access,
int32 version,
const QByteArray &fileReference, const QByteArray &fileReference,
TimeId date, TimeId date,
const QVector<MTPDocumentAttribute> &attributes, const QVector<MTPDocumentAttribute> &attributes,
@ -1041,7 +1039,6 @@ not_null<DocumentData*> Session::document(
documentApplyFields( documentApplyFields(
result, result,
access, access,
version,
fileReference, fileReference,
date, date,
attributes, attributes,
@ -1120,7 +1117,6 @@ DocumentData *Session::documentFromWeb(
const auto result = document( const auto result = document(
rand_value<DocumentId>(), rand_value<DocumentId>(),
uint64(0), uint64(0),
int32(0),
QByteArray(), QByteArray(),
unixtime(), unixtime(),
data.vattributes.v, data.vattributes.v,
@ -1142,7 +1138,6 @@ DocumentData *Session::documentFromWeb(
const auto result = document( const auto result = document(
rand_value<DocumentId>(), rand_value<DocumentId>(),
uint64(0), uint64(0),
int32(0),
QByteArray(), QByteArray(),
unixtime(), unixtime(),
data.vattributes.v, data.vattributes.v,
@ -1169,7 +1164,6 @@ void Session::documentApplyFields(
documentApplyFields( documentApplyFields(
document, document,
data.vaccess_hash.v, data.vaccess_hash.v,
data.vversion.v,
data.vfile_reference.v, data.vfile_reference.v,
data.vdate.v, data.vdate.v,
data.vattributes.v, data.vattributes.v,
@ -1183,7 +1177,6 @@ void Session::documentApplyFields(
void Session::documentApplyFields( void Session::documentApplyFields(
not_null<DocumentData*> document, not_null<DocumentData*> document,
const uint64 &access, const uint64 &access,
int32 version,
const QByteArray &fileReference, const QByteArray &fileReference,
TimeId date, TimeId date,
const QVector<MTPDocumentAttribute> &attributes, const QVector<MTPDocumentAttribute> &attributes,
@ -1196,7 +1189,6 @@ void Session::documentApplyFields(
return; return;
} }
document->setattributes(attributes); document->setattributes(attributes);
document->setRemoteVersion(version);
if (dc != 0 && access != 0) { if (dc != 0 && access != 0) {
document->setRemoteLocation(dc, access, fileReference); document->setRemoteLocation(dc, access, fileReference);
} }

View file

@ -269,7 +269,6 @@ public:
not_null<DocumentData*> document( not_null<DocumentData*> document(
DocumentId id, DocumentId id,
const uint64 &access, const uint64 &access,
int32 version,
const QByteArray &fileReference, const QByteArray &fileReference,
TimeId date, TimeId date,
const QVector<MTPDocumentAttribute> &attributes, const QVector<MTPDocumentAttribute> &attributes,
@ -452,7 +451,6 @@ private:
void documentApplyFields( void documentApplyFields(
not_null<DocumentData*> document, not_null<DocumentData*> document,
const uint64 &access, const uint64 &access,
int32 version,
const QByteArray &fileReference, const QByteArray &fileReference,
TimeId date, TimeId date,
const QVector<MTPDocumentAttribute> &attributes, const QVector<MTPDocumentAttribute> &attributes,

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "base/value_ordering.h" #include "base/value_ordering.h"
#include "ui/text/text.h" // For QFIXED_MAX
class HistoryItem; class HistoryItem;
using HistoryItemsList = std::vector<not_null<HistoryItem*>>; using HistoryItemsList = std::vector<not_null<HistoryItem*>>;

View file

@ -399,7 +399,6 @@ Document ParseDocument(
result.file.location.data = MTP_inputDocumentFileLocation( result.file.location.data = MTP_inputDocumentFileLocation(
data.vid, data.vid,
data.vaccess_hash, data.vaccess_hash,
data.vversion,
data.vfile_reference); data.vfile_reference);
const auto path = result.file.suggestedPath = suggestedFolder const auto path = result.file.suggestedPath = suggestedFolder
+ DocumentFolder(result) + '/' + DocumentFolder(result) + '/'

View file

@ -203,15 +203,17 @@ void showBox(
} // namespace internal } // namespace internal
void showMediaPreview(DocumentData *document) { void showMediaPreview(
Data::FileOrigin origin,
not_null<DocumentData*> document) {
if (auto w = App::wnd()) { if (auto w = App::wnd()) {
w->ui_showMediaPreview(document); w->ui_showMediaPreview(origin, document);
} }
} }
void showMediaPreview(PhotoData *photo) { void showMediaPreview(Data::FileOrigin origin, not_null<PhotoData*> photo) {
if (auto w = App::wnd()) { if (auto w = App::wnd()) {
w->ui_showMediaPreview(photo); w->ui_showMediaPreview(origin, photo);
} }
} }

View file

@ -98,8 +98,10 @@ void showBox(
} // namespace internal } // namespace internal
void showMediaPreview(DocumentData *document); void showMediaPreview(
void showMediaPreview(PhotoData *photo); Data::FileOrigin origin,
not_null<DocumentData*> document);
void showMediaPreview(Data::FileOrigin origin, not_null<PhotoData*> photo);
void hideMediaPreview(); void hideMediaPreview();
template <typename BoxType> template <typename BoxType>

View file

@ -1081,7 +1081,9 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
} }
void InnerWidget::savePhotoToFile(PhotoData *photo) { void InnerWidget::savePhotoToFile(PhotoData *photo) {
if (!photo || !photo->date || !photo->loaded()) return; if (!photo || !photo->date || !photo->loaded()) {
return;
}
auto filter = qsl("JPEG Image (*.jpg);;") + FileDialog::AllFilesFilter(); auto filter = qsl("JPEG Image (*.jpg);;") + FileDialog::AllFilesFilter();
FileDialog::GetWritePath( FileDialog::GetWritePath(
@ -1091,19 +1093,19 @@ void InnerWidget::savePhotoToFile(PhotoData *photo) {
filedialogDefaultName(qsl("photo"), qsl(".jpg")), filedialogDefaultName(qsl("photo"), qsl(".jpg")),
crl::guard(this, [=](const QString &result) { crl::guard(this, [=](const QString &result) {
if (!result.isEmpty()) { if (!result.isEmpty()) {
photo->full->pix().toImage().save(result, "JPG"); photo->full->pix(Data::FileOrigin()).toImage().save(result, "JPG");
} }
})); }));
} }
void InnerWidget::saveDocumentToFile(DocumentData *document) { void InnerWidget::saveDocumentToFile(DocumentData *document) {
DocumentSaveClickHandler::doSave(document, true); DocumentSaveClickHandler::Save(Data::FileOrigin(), document, true);
} }
void InnerWidget::copyContextImage(PhotoData *photo) { void InnerWidget::copyContextImage(PhotoData *photo) {
if (!photo || !photo->date || !photo->loaded()) return; if (!photo || !photo->date || !photo->loaded()) return;
QApplication::clipboard()->setPixmap(photo->full->pix()); QApplication::clipboard()->setPixmap(photo->full->pix(Data::FileOrigin()));
} }
void InnerWidget::copySelectedText() { void InnerWidget::copySelectedText() {

View file

@ -1536,7 +1536,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}); });
} }
_menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsVoice ? lng_context_save_audio : (lnkIsAudio ? lng_context_save_audio_file : lng_context_save_file))), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] { _menu->addAction(lang(lnkIsVideo ? lng_context_save_video : (lnkIsVoice ? lng_context_save_audio : (lnkIsAudio ? lng_context_save_audio_file : lng_context_save_file))), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] {
saveDocumentToFile(document); saveDocumentToFile(itemId, document);
})); }));
} }
} }
@ -1639,8 +1639,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
toggleFavedSticker(document); toggleFavedSticker(document);
}); });
} }
_menu->addAction(lang(lng_context_save_image), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [this, document] { _menu->addAction(lang(lng_context_save_image), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] {
saveDocumentToFile(document); saveDocumentToFile(itemId, document);
})); }));
} }
} }
@ -1753,7 +1753,7 @@ void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
qsl(".jpg")), qsl(".jpg")),
crl::guard(this, [=](const QString &result) { crl::guard(this, [=](const QString &result) {
if (!result.isEmpty()) { if (!result.isEmpty()) {
photo->full->pix().toImage().save(result, "JPG"); photo->full->pix(Data::FileOrigin()).toImage().save(result, "JPG");
} }
})); }));
} }
@ -1761,7 +1761,7 @@ void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
void HistoryInner::copyContextImage(not_null<PhotoData*> photo) { void HistoryInner::copyContextImage(not_null<PhotoData*> photo) {
if (!photo->date || !photo->loaded()) return; if (!photo->date || !photo->loaded()) return;
QApplication::clipboard()->setPixmap(photo->full->pix()); QApplication::clipboard()->setPixmap(photo->full->pix(Data::FileOrigin()));
} }
void HistoryInner::showStickerPackInfo(not_null<DocumentData*> document) { void HistoryInner::showStickerPackInfo(not_null<DocumentData*> document) {
@ -1791,8 +1791,10 @@ void HistoryInner::showContextInFolder(not_null<DocumentData*> document) {
} }
} }
void HistoryInner::saveDocumentToFile(not_null<DocumentData*> document) { void HistoryInner::saveDocumentToFile(
DocumentSaveClickHandler::doSave(document, true); FullMsgId contextId,
not_null<DocumentData*> document) {
DocumentSaveClickHandler::Save(contextId, document, true);
} }
void HistoryInner::openContextGif(FullMsgId itemId) { void HistoryInner::openContextGif(FullMsgId itemId) {

View file

@ -209,7 +209,9 @@ private:
void copyContextText(FullMsgId itemId); void copyContextText(FullMsgId itemId);
void showContextInFolder(not_null<DocumentData*> document); void showContextInFolder(not_null<DocumentData*> document);
void savePhotoToFile(not_null<PhotoData*> photo); void savePhotoToFile(not_null<PhotoData*> photo);
void saveDocumentToFile(not_null<DocumentData*> document); void saveDocumentToFile(
FullMsgId contextId,
not_null<DocumentData*> document);
void copyContextImage(not_null<PhotoData*> photo); void copyContextImage(not_null<PhotoData*> photo);
void showStickerPackInfo(not_null<DocumentData*> document); void showStickerPackInfo(not_null<DocumentData*> document);
void toggleFavedSticker(not_null<DocumentData*> document); void toggleFavedSticker(not_null<DocumentData*> document);

View file

@ -262,7 +262,7 @@ void HistoryMessageReply::paint(
auto to = rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x); auto to = rtlrect(x + st::msgReplyBarSkip, y + st::msgReplyPadding.top() + st::msgReplyBarPos.y(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height(), w + 2 * x);
auto previewWidth = replyPreview->width() / cIntRetinaFactor(); auto previewWidth = replyPreview->width() / cIntRetinaFactor();
auto previewHeight = replyPreview->height() / cIntRetinaFactor(); auto previewHeight = replyPreview->height() / cIntRetinaFactor();
auto preview = replyPreview->pixSingle(previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr); auto preview = replyPreview->pixSingle(replyToMsg->fullId(), previewWidth, previewHeight, to.width(), to.height(), ImageRoundRadius::Small, RectPart::AllCorners, selected ? &st::msgStickerOverlay : nullptr);
p.drawPixmap(to.x(), to.y(), preview); p.drawPixmap(to.x(), to.y(), preview);
} }
} }

View file

@ -222,9 +222,12 @@ void LocationManager::failed(LocationData *data) {
serverRedirects.remove(data); serverRedirects.remove(data);
} }
void LocationData::load() { void LocationData::load(Data::FileOrigin origin) {
if (!thumb->isNull()) return thumb->load(false, false); if (!thumb->isNull()) {
if (loading) return; return thumb->load(origin, false, false);
} else if (loading) {
return;
}
loading = true; loading = true;
if (locationManager) { if (locationManager) {

View file

@ -70,7 +70,7 @@ struct LocationData {
ImagePtr thumb; ImagePtr thumb;
bool loading; bool loading;
void load(); void load(Data::FileOrigin origin);
}; };
class LocationClickHandler : public ClickHandler { class LocationClickHandler : public ClickHandler {

View file

@ -258,7 +258,7 @@ HistoryPhoto::HistoryPhoto(
not_null<Element*> parent, not_null<Element*> parent,
not_null<HistoryItem*> realParent, not_null<HistoryItem*> realParent,
not_null<PhotoData*> photo) not_null<PhotoData*> photo)
: HistoryFileMedia(parent) : HistoryFileMedia(parent, realParent)
, _data(photo) , _data(photo)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
const auto fullId = realParent->fullId(); const auto fullId = realParent->fullId();
@ -275,7 +275,7 @@ HistoryPhoto::HistoryPhoto(
not_null<PeerData*> chat, not_null<PeerData*> chat,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
int width) int width)
: HistoryFileMedia(parent) : HistoryFileMedia(parent, parent->data())
, _data(photo) , _data(photo)
, _serviceWidth(width) { , _serviceWidth(width) {
create(parent->data()->fullId(), chat); create(parent->data()->fullId(), chat);
@ -286,7 +286,7 @@ void HistoryPhoto::create(FullMsgId contextId, PeerData *chat) {
std::make_shared<PhotoOpenClickHandler>(_data, contextId, chat), std::make_shared<PhotoOpenClickHandler>(_data, contextId, chat),
std::make_shared<PhotoSaveClickHandler>(_data, contextId, chat), std::make_shared<PhotoSaveClickHandler>(_data, contextId, chat),
std::make_shared<PhotoCancelClickHandler>(_data, contextId, chat)); std::make_shared<PhotoCancelClickHandler>(_data, contextId, chat));
_data->thumb->load(); _data->thumb->load(contextId);
} }
QSize HistoryPhoto::countOptimalSize() { QSize HistoryPhoto::countOptimalSize() {
@ -375,7 +375,7 @@ QSize HistoryPhoto::countCurrentSize(int newWidth) {
void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const { void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
_data->automaticLoad(_parent->data()); _data->automaticLoad(_realParent->fullId(), _parent->data());
auto selected = (selection == FullSelection); auto selected = (selection == FullSelection);
auto loaded = _data->loaded(); auto loaded = _data->loaded();
auto displayLoading = _data->displayLoading(); auto displayLoading = _data->displayLoading();
@ -397,8 +397,8 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim
auto rthumb = rtlrect(paintx, painty, paintw, painth, width()); auto rthumb = rtlrect(paintx, painty, paintw, painth, width());
if (_serviceWidth > 0) { if (_serviceWidth > 0) {
const auto pix = loaded const auto pix = loaded
? _data->full->pixCircled(_pixw, _pixh) ? _data->full->pixCircled(_realParent->fullId(), _pixw, _pixh)
: _data->thumb->pixBlurredCircled(_pixw, _pixh); : _data->thumb->pixBlurredCircled(_realParent->fullId(), _pixw, _pixh);
p.drawPixmap(rthumb.topLeft(), pix); p.drawPixmap(rthumb.topLeft(), pix);
} else { } else {
if (bubble) { if (bubble) {
@ -417,8 +417,8 @@ void HistoryPhoto::draw(Painter &p, const QRect &r, TextSelection selection, Tim
auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None)
| ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None)); | ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None));
const auto pix = loaded const auto pix = loaded
? _data->full->pixSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners) ? _data->full->pixSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners)
: _data->thumb->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners); : _data->thumb->pixBlurredSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners);
p.drawPixmap(rthumb.topLeft(), pix); p.drawPixmap(rthumb.topLeft(), pix);
if (selected) { if (selected) {
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners); App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
@ -559,7 +559,7 @@ void HistoryPhoto::drawGrouped(
RectParts corners, RectParts corners,
not_null<uint64*> cacheKey, not_null<uint64*> cacheKey,
not_null<QPixmap*> cache) const { not_null<QPixmap*> cache) const {
_data->automaticLoad(_parent->data()); _data->automaticLoad(_realParent->fullId(), _parent->data());
validateGroupedCache(geometry, corners, cacheKey, cache); validateGroupedCache(geometry, corners, cacheKey, cache);
@ -715,7 +715,7 @@ void HistoryPhoto::validateGroupedCache(
const auto &image = loaded ? _data->full : _data->thumb; const auto &image = loaded ? _data->full : _data->thumb;
*cacheKey = key; *cacheKey = key;
*cache = image->pixNoCache(pixWidth, pixHeight, options, width, height); *cache = image->pixNoCache(_realParent->fullId(), pixWidth, pixHeight, options, width, height);
} }
TextWithEntities HistoryPhoto::selectedText(TextSelection selection) const { TextWithEntities HistoryPhoto::selectedText(TextSelection selection) const {
@ -747,7 +747,7 @@ HistoryVideo::HistoryVideo(
not_null<Element*> parent, not_null<Element*> parent,
not_null<HistoryItem*> realParent, not_null<HistoryItem*> realParent,
not_null<DocumentData*> document) not_null<DocumentData*> document)
: HistoryFileMedia(parent) : HistoryFileMedia(parent, realParent)
, _data(document) , _data(document)
, _thumbw(1) , _thumbw(1)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
@ -757,7 +757,7 @@ HistoryVideo::HistoryVideo(
setStatusSize(FileStatusSizeReady); setStatusSize(FileStatusSizeReady);
_data->thumb->load(); _data->thumb->load(realParent->fullId());
} }
QSize HistoryVideo::countOptimalSize() { QSize HistoryVideo::countOptimalSize() {
@ -837,7 +837,7 @@ QSize HistoryVideo::countCurrentSize(int newWidth) {
void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const { void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
_data->automaticLoad(_parent->data()); _data->automaticLoad(_realParent->fullId(), _parent->data());
bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
bool selected = (selection == FullSelection); bool selected = (selection == FullSelection);
@ -871,7 +871,7 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, Tim
auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None)
| ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None)); | ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None));
QRect rthumb(rtlrect(paintx, painty, paintw, painth, width())); QRect rthumb(rtlrect(paintx, painty, paintw, painth, width()));
p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_thumbw, 0, paintw, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_realParent->fullId(), _thumbw, 0, paintw, painth, roundRadius, roundCorners));
if (selected) { if (selected) {
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners); App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
} }
@ -1010,7 +1010,7 @@ void HistoryVideo::drawGrouped(
RectParts corners, RectParts corners,
not_null<uint64*> cacheKey, not_null<uint64*> cacheKey,
not_null<QPixmap*> cache) const { not_null<QPixmap*> cache) const {
_data->automaticLoad(_parent->data()); _data->automaticLoad(_realParent->fullId(), _parent->data());
validateGroupedCache(geometry, corners, cacheKey, cache); validateGroupedCache(geometry, corners, cacheKey, cache);
@ -1155,7 +1155,7 @@ void HistoryVideo::validateGroupedCache(
const auto &image = _data->thumb; const auto &image = _data->thumb;
*cacheKey = key; *cacheKey = key;
*cache = image->pixNoCache(pixWidth, pixHeight, options, width, height); *cache = image->pixNoCache(_realParent->fullId(), pixWidth, pixHeight, options, width, height);
} }
void HistoryVideo::setStatusSize(int newSize) const { void HistoryVideo::setStatusSize(int newSize) const {
@ -1208,7 +1208,7 @@ void HistoryVideo::updateStatusText() const {
HistoryDocument::HistoryDocument( HistoryDocument::HistoryDocument(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document) not_null<DocumentData*> document)
: HistoryFileMedia(parent) : HistoryFileMedia(parent, parent->data())
, _data(document) { , _data(document) {
const auto item = parent->data(); const auto item = parent->data();
auto caption = createCaption(item); auto caption = createCaption(item);
@ -1293,7 +1293,7 @@ QSize HistoryDocument::countOptimalSize() {
} }
auto thumbed = Get<HistoryDocumentThumbed>(); auto thumbed = Get<HistoryDocumentThumbed>();
if (thumbed) { if (thumbed) {
_data->thumb->load(); _data->thumb->load(_realParent->fullId());
auto tw = convertScale(_data->thumb->width()); auto tw = convertScale(_data->thumb->width());
auto th = convertScale(_data->thumb->height()); auto th = convertScale(_data->thumb->height());
if (tw > th) { if (tw > th) {
@ -1378,7 +1378,7 @@ QSize HistoryDocument::countCurrentSize(int newWidth) {
void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const { void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
_data->automaticLoad(_parent->data()); _data->automaticLoad(_realParent->fullId(), _parent->data());
bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
bool selected = (selection == FullSelection); bool selected = (selection == FullSelection);
@ -1409,9 +1409,9 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width())); QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width()));
QPixmap thumb; QPixmap thumb;
if (loaded) { if (loaded) {
thumb = _data->thumb->pixSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); thumb = _data->thumb->pixSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
} else { } else {
thumb = _data->thumb->pixBlurredSingle(thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius); thumb = _data->thumb->pixBlurredSingle(_realParent->fullId(), thumbed->_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize, roundRadius);
} }
p.drawPixmap(rthumb.topLeft(), thumb); p.drawPixmap(rthumb.topLeft(), thumb);
if (selected) { if (selected) {
@ -1929,7 +1929,7 @@ TextWithEntities HistoryDocument::getCaption() const {
HistoryGif::HistoryGif( HistoryGif::HistoryGif(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document) not_null<DocumentData*> document)
: HistoryFileMedia(parent) : HistoryFileMedia(parent, parent->data())
, _data(document) , _data(document)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
const auto item = parent->data(); const auto item = parent->data();
@ -1938,7 +1938,7 @@ HistoryGif::HistoryGif(
setStatusSize(FileStatusSizeReady); setStatusSize(FileStatusSizeReady);
_caption = createCaption(item); _caption = createCaption(item);
_data->thumb->load(); _data->thumb->load(item->fullId());
} }
QSize HistoryGif::countOptimalSize() { QSize HistoryGif::countOptimalSize() {
@ -2116,7 +2116,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
const auto item = _parent->data(); const auto item = _parent->data();
_data->automaticLoad(item); _data->automaticLoad(_realParent->fullId(), item);
auto loaded = _data->loaded(); auto loaded = _data->loaded();
auto displayLoading = (item->id < 0) || _data->displayLoading(); auto displayLoading = (item->id < 0) || _data->displayLoading();
auto selected = (selection == FullSelection); auto selected = (selection == FullSelection);
@ -2220,7 +2220,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
} }
} }
} else { } else {
p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_thumbw, _thumbh, usew, painth, roundRadius, roundCorners)); p.drawPixmap(rthumb.topLeft(), _data->thumb->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, usew, painth, roundRadius, roundCorners));
} }
if (selected) { if (selected) {
@ -2793,7 +2793,7 @@ HistorySticker::HistorySticker(
: HistoryMedia(parent) : HistoryMedia(parent)
, _data(document) , _data(document)
, _emoji(_data->sticker()->alt) { , _emoji(_data->sticker()->alt) {
_data->thumb->load(); _data->thumb->load(parent->data()->fullId());
if (auto emoji = Ui::Emoji::Find(_emoji)) { if (auto emoji = Ui::Emoji::Find(_emoji)) {
_emoji = emoji->text(); _emoji = emoji->text();
} }
@ -2881,15 +2881,15 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
if (selected) { if (selected) {
if (sticker->img->isNull()) { if (sticker->img->isNull()) {
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurredColored(st::msgStickerOverlay, _pixw, _pixh)); p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurredColored(item->fullId(), st::msgStickerOverlay, _pixw, _pixh));
} else { } else {
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pixColored(st::msgStickerOverlay, _pixw, _pixh)); p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pixColored(item->fullId(), st::msgStickerOverlay, _pixw, _pixh));
} }
} else { } else {
if (sticker->img->isNull()) { if (sticker->img->isNull()) {
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurred(_pixw, _pixh)); p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), _data->thumb->pixBlurred(item->fullId(), _pixw, _pixh));
} else { } else {
p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pix(_pixw, _pixh)); p.drawPixmap(QPoint(usex + (usew - _pixw) / 2, (minHeight() - _pixh) / 2), sticker->img->pix(item->fullId(), _pixw, _pixh));
} }
} }
@ -3616,7 +3616,8 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, T
auto lineHeight = unitedLineHeight(); auto lineHeight = unitedLineHeight();
if (_asArticle) { if (_asArticle) {
_data->photo->medium->load(false, false); const auto contextId = _parent->data()->fullId();
_data->photo->medium->load(contextId, false, false);
bool full = _data->photo->medium->loaded(); bool full = _data->photo->medium->loaded();
QPixmap pix; QPixmap pix;
auto pw = qMax(_pixw, lineHeight); auto pw = qMax(_pixw, lineHeight);
@ -3629,9 +3630,9 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, T
pixw = qRound(pixw * coef); pixw = qRound(pixw * coef);
} }
if (full) { if (full) {
pix = _data->photo->medium->pixSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small); pix = _data->photo->medium->pixSingle(contextId, pixw, pixh, pw, ph, ImageRoundRadius::Small);
} else { } else {
pix = _data->photo->thumb->pixBlurredSingle(pixw, pixh, pw, ph, ImageRoundRadius::Small); pix = _data->photo->thumb->pixBlurredSingle(contextId, pixw, pixh, pw, ph, ImageRoundRadius::Small);
} }
p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix); p.drawPixmapLeft(padding.left() + paintw - pw, tshift, width(), pix);
if (selected) { if (selected) {
@ -4802,7 +4803,8 @@ void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection,
App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners); App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners);
} }
_data->load(); const auto contextId = _parent->data()->fullId();
_data->load(contextId);
auto roundRadius = ImageRoundRadius::Large; auto roundRadius = ImageRoundRadius::Large;
auto roundCorners = ((isBubbleTop() && _title.isEmpty() && _description.isEmpty()) ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) auto roundCorners = ((isBubbleTop() && _title.isEmpty() && _description.isEmpty()) ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None)
| (isBubbleBottom() ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None); | (isBubbleBottom() ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None);
@ -4811,13 +4813,13 @@ void HistoryLocation::draw(Painter &p, const QRect &r, TextSelection selection,
auto w = _data->thumb->width(), h = _data->thumb->height(); auto w = _data->thumb->width(), h = _data->thumb->height();
QPixmap pix; QPixmap pix;
if (paintw * h == painth * w || (w == fullWidth() && h == fullHeight())) { if (paintw * h == painth * w || (w == fullWidth() && h == fullHeight())) {
pix = _data->thumb->pixSingle(paintw, painth, paintw, painth, roundRadius, roundCorners); pix = _data->thumb->pixSingle(contextId, paintw, painth, paintw, painth, roundRadius, roundCorners);
} else if (paintw * h > painth * w) { } else if (paintw * h > painth * w) {
auto nw = painth * w / h; auto nw = painth * w / h;
pix = _data->thumb->pixSingle(nw, painth, paintw, painth, roundRadius, roundCorners); pix = _data->thumb->pixSingle(contextId, nw, painth, paintw, painth, roundRadius, roundCorners);
} else { } else {
auto nh = paintw * h / w; auto nh = paintw * h / w;
pix = _data->thumb->pixSingle(paintw, nh, paintw, painth, roundRadius, roundCorners); pix = _data->thumb->pixSingle(contextId, paintw, nh, paintw, painth, roundRadius, roundCorners);
} }
p.drawPixmap(rthumb.topLeft(), pix); p.drawPixmap(rthumb.topLeft(), pix);
} else { } else {

View file

@ -45,7 +45,12 @@ QString FillAmountAndCurrency(uint64 amount, const QString &currency);
class HistoryFileMedia : public HistoryMedia { class HistoryFileMedia : public HistoryMedia {
public: public:
using HistoryMedia::HistoryMedia; HistoryFileMedia(
not_null<Element*> parent,
not_null<HistoryItem*> realParent)
: HistoryMedia(parent)
, _realParent(realParent) {
}
bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override { bool toggleSelectionByHandlerClick(const ClickHandlerPtr &p) const override {
return p == _openl || p == _savel || p == _cancell; return p == _openl || p == _savel || p == _cancell;
@ -67,6 +72,8 @@ public:
protected: protected:
using FileClickHandlerPtr = std::shared_ptr<FileClickHandler>; using FileClickHandlerPtr = std::shared_ptr<FileClickHandler>;
not_null<HistoryItem*> _realParent;
FileClickHandlerPtr _openl, _savel, _cancell; FileClickHandlerPtr _openl, _savel, _cancell;
void setLinks( void setLinks(

View file

@ -6616,7 +6616,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
auto replyPreview = drawMsgText->media()->replyPreview(); auto replyPreview = drawMsgText->media()->replyPreview();
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); auto to = QRect(replyLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(drawMsgText->fullId(), replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
} }
replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); replyLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
@ -6651,10 +6651,10 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (!preview->isNull()) { if (!preview->isNull()) {
auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (preview->width() == preview->height()) { if (preview->width() == preview->height()) {
p.drawPixmap(to.x(), to.y(), preview->pix()); p.drawPixmap(to.x(), to.y(), preview->pix(firstItem->fullId()));
} else { } else {
auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width()); auto from = (preview->width() > preview->height()) ? QRect((preview->width() - preview->height()) / 2, 0, preview->height(), preview->height()) : QRect(0, (preview->height() - preview->width()) / 2, preview->width(), preview->width());
p.drawPixmap(to, preview->pix(), from); p.drawPixmap(to, preview->pix(firstItem->fullId()), from);
} }
forwardLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); forwardLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }
@ -6670,14 +6670,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
auto previewLeft = st::historyReplySkip + st::webPageLeft; auto previewLeft = st::historyReplySkip + st::webPageLeft;
p.fillRect(st::historyReplySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor); p.fillRect(st::historyReplySkip, backy + st::msgReplyPadding.top(), st::webPageBar, st::msgReplyBarSize.height(), st::msgInReplyBarColor);
if ((_previewData->photo && !_previewData->photo->thumb->isNull()) || (_previewData->document && !_previewData->document->thumb->isNull())) { if ((_previewData->photo && !_previewData->photo->thumb->isNull()) || (_previewData->document && !_previewData->document->thumb->isNull())) {
auto replyPreview = _previewData->photo ? _previewData->photo->makeReplyPreview() : _previewData->document->makeReplyPreview(); auto replyPreview = _previewData->photo ? _previewData->photo->makeReplyPreview(Data::FileOrigin()) : _previewData->document->makeReplyPreview(Data::FileOrigin());
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
if (replyPreview->width() == replyPreview->height()) { if (replyPreview->width() == replyPreview->height()) {
p.drawPixmap(to.x(), to.y(), replyPreview->pix()); p.drawPixmap(to.x(), to.y(), replyPreview->pix(Data::FileOrigin()));
} else { } else {
auto from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width()); auto from = (replyPreview->width() > replyPreview->height()) ? QRect((replyPreview->width() - replyPreview->height()) / 2, 0, replyPreview->height(), replyPreview->height()) : QRect(0, (replyPreview->height() - replyPreview->width()) / 2, replyPreview->width(), replyPreview->width());
p.drawPixmap(to, replyPreview->pix(), from); p.drawPixmap(to, replyPreview->pix(Data::FileOrigin()), from);
} }
} }
previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); previewLeft += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
@ -6782,7 +6782,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
ImagePtr replyPreview = _pinnedBar->msg->media()->replyPreview(); ImagePtr replyPreview = _pinnedBar->msg->media()->replyPreview();
if (!replyPreview->isNull()) { if (!replyPreview->isNull()) {
QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height()); QRect to(left, top, st::msgReplyBarSize.height(), st::msgReplyBarSize.height());
p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small)); p.drawPixmap(to.x(), to.y(), replyPreview->pixSingle(_pinnedBar->msg->fullId(), replyPreview->width() / cIntRetinaFactor(), replyPreview->height() / cIntRetinaFactor(), to.width(), to.height(), ImageRoundRadius::Small));
} }
left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x(); left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
} }

View file

@ -55,7 +55,7 @@ void SavePhotoToFile(not_null<PhotoData*> photo) {
filedialogDefaultName(qsl("photo"), qsl(".jpg")), filedialogDefaultName(qsl("photo"), qsl(".jpg")),
crl::guard(&Auth(), [=](const QString &result) { crl::guard(&Auth(), [=](const QString &result) {
if (!result.isEmpty()) { if (!result.isEmpty()) {
photo->full->pix().toImage().save(result, "JPG"); photo->full->pix(Data::FileOrigin()).toImage().save(result, "JPG");
} }
})); }));
} }
@ -65,7 +65,7 @@ void CopyImage(not_null<PhotoData*> photo) {
return; return;
} }
QApplication::clipboard()->setPixmap(photo->full->pix()); QApplication::clipboard()->setPixmap(photo->full->pix(Data::FileOrigin()));
} }
void ShowStickerPackInfo(not_null<DocumentData*> document) { void ShowStickerPackInfo(not_null<DocumentData*> document) {
@ -121,6 +121,7 @@ void ShowInFolder(not_null<DocumentData*> document) {
void AddSaveDocumentAction( void AddSaveDocumentAction(
not_null<Ui::PopupMenu*> menu, not_null<Ui::PopupMenu*> menu,
Data::FileOrigin origin,
not_null<DocumentData*> document) { not_null<DocumentData*> document) {
menu->addAction( menu->addAction(
lang(document->isVideoFile() lang(document->isVideoFile()
@ -135,7 +136,7 @@ void AddSaveDocumentAction(
App::LambdaDelayed( App::LambdaDelayed(
st::defaultDropdownMenu.menu.ripple.hideDuration, st::defaultDropdownMenu.menu.ripple.hideDuration,
&Auth(), &Auth(),
[=] { DocumentSaveClickHandler::doSave(document, true); })); [=] { DocumentSaveClickHandler::Save(origin, document, true); }));
} }
void AddDocumentActions( void AddDocumentActions(
@ -176,7 +177,7 @@ void AddDocumentActions(
: lng_context_show_in_folder), : lng_context_show_in_folder),
[=] { ShowInFolder(document); }); [=] { ShowInFolder(document); });
} }
AddSaveDocumentAction(menu, document); AddSaveDocumentAction(menu, contextId, document);
} }
void CopyPostLink(FullMsgId itemId) { void CopyPostLink(FullMsgId itemId) {

View file

@ -1220,10 +1220,11 @@ void ListWidget::showContextMenu(
auto link = ClickHandler::getActive(); auto link = ClickHandler::getActive();
const auto itemFullId = item->fullId();
_contextMenu = base::make_unique_q<Ui::PopupMenu>(this); _contextMenu = base::make_unique_q<Ui::PopupMenu>(this);
_contextMenu->addAction( _contextMenu->addAction(
lang(lng_context_to_msg), lang(lng_context_to_msg),
[itemFullId = item->fullId()] { [itemFullId] {
if (auto item = App::histItemById(itemFullId)) { if (auto item = App::histItemById(itemFullId)) {
Ui::showPeerHistoryAtItem(item); Ui::showPeerHistoryAtItem(item);
} }
@ -1271,8 +1272,11 @@ void ListWidget::showContextMenu(
auto handler = App::LambdaDelayed( auto handler = App::LambdaDelayed(
st::defaultDropdownMenu.menu.ripple.hideDuration, st::defaultDropdownMenu.menu.ripple.hideDuration,
this, this,
[document] { [=] {
DocumentSaveClickHandler::doSave(document, true); DocumentSaveClickHandler::Save(
itemFullId,
document,
true);
}); });
_contextMenu->addAction( _contextMenu->addAction(
lang(isVideo lang(isVideo

View file

@ -134,8 +134,8 @@ int Gif::resizeGetHeight(int width) {
} }
void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) const { void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) const {
DocumentData *document = getShownDocument(); const auto document = getShownDocument();
document->automaticLoad(nullptr); document->automaticLoad(fileOrigin(), nullptr);
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading(); bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
if (loaded && !_gif && !_gif.isBad()) { if (loaded && !_gif && !_gif.isBad()) {
@ -286,25 +286,26 @@ QSize Gif::countFrameSize() const {
} }
void Gif::prepareThumb(int32 width, int32 height, const QSize &frame) const { void Gif::prepareThumb(int32 width, int32 height, const QSize &frame) const {
if (DocumentData *document = getShownDocument()) { const auto origin = fileOrigin();
if (const auto document = getShownDocument()) {
if (!document->thumb->isNull()) { if (!document->thumb->isNull()) {
if (document->thumb->loaded()) { if (document->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = document->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = document->thumb->pixNoCache(origin, frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
document->thumb->load(); document->thumb->load(origin);
} }
} }
} else { } else {
ImagePtr thumb = getResultThumb(); const auto thumb = getResultThumb();
if (!thumb->isNull()) { if (!thumb->isNull()) {
if (thumb->loaded()) { if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(origin, frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
} }
@ -375,17 +376,9 @@ void Sticker::initDimensions() {
void Sticker::preload() const { void Sticker::preload() const {
if (const auto document = getShownDocument()) { if (const auto document = getShownDocument()) {
const auto goodThumb = document->hasGoodStickerThumb(); document->checkStickerThumb();
if (goodThumb) { } else if (const auto thumb = getResultThumb()) {
document->thumb->load(); thumb->load(fileOrigin());
} else {
document->checkSticker();
}
} else {
const auto thumb = getResultThumb();
if (!thumb->isNull()) {
thumb->load();
}
} }
} }
@ -441,33 +434,31 @@ QSize Sticker::getThumbSize() const {
void Sticker::prepareThumb() const { void Sticker::prepareThumb() const {
if (const auto document = getShownDocument()) { if (const auto document = getShownDocument()) {
const auto goodThumb = document->hasGoodStickerThumb(); document->checkStickerThumb();
if (goodThumb) {
document->thumb->load();
} else {
document->checkSticker();
}
const auto sticker = goodThumb const auto sticker = document->getStickerThumb();
? document->thumb
: document->sticker()
? document->sticker()->img
: ImagePtr();
if (!_thumbLoaded && !sticker->isNull() && sticker->loaded()) { if (!_thumbLoaded && !sticker->isNull() && sticker->loaded()) {
QSize thumbSize = getThumbSize(); const auto thumbSize = getThumbSize();
_thumb = sticker->pix(thumbSize.width(), thumbSize.height()); _thumb = sticker->pix(
document->stickerSetOrigin(),
thumbSize.width(),
thumbSize.height());
_thumbLoaded = true; _thumbLoaded = true;
} }
} else { } else {
ImagePtr thumb = getResultThumb(); const auto origin = fileOrigin();
const auto thumb = getResultThumb();
if (thumb->loaded()) { if (thumb->loaded()) {
if (!_thumbLoaded) { if (!_thumbLoaded) {
QSize thumbSize = getThumbSize(); const auto thumbSize = getThumbSize();
_thumb = thumb->pix(thumbSize.width(), thumbSize.height()); _thumb = thumb->pix(
origin,
thumbSize.width(),
thumbSize.height());
_thumbLoaded = true; _thumbLoaded = true;
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
} }
@ -546,28 +537,29 @@ QSize Photo::countFrameSize() const {
} }
void Photo::prepareThumb(int32 width, int32 height, const QSize &frame) const { void Photo::prepareThumb(int32 width, int32 height, const QSize &frame) const {
if (PhotoData *photo = getShownPhoto()) { const auto origin = fileOrigin();
if (const auto photo = getShownPhoto()) {
if (photo->medium->loaded()) { if (photo->medium->loaded()) {
if (!_thumbLoaded || _thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (!_thumbLoaded || _thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = photo->medium->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = photo->medium->pixNoCache(origin, frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
_thumbLoaded = true; _thumbLoaded = true;
} else { } else {
if (photo->thumb->loaded()) { if (photo->thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = photo->thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = photo->thumb->pixNoCache(origin, frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} }
photo->medium->load(); photo->medium->load(origin);
} }
} else { } else {
ImagePtr thumb = getResultThumb(); const auto thumb = getResultThumb();
if (thumb->loaded()) { if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = thumb->pixNoCache(frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(origin, frame.width() * cIntRetinaFactor(), frame.height() * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
} }
@ -660,7 +652,8 @@ TextState Video::getState(
} }
void Video::prepareThumb(int32 width, int32 height) const { void Video::prepareThumb(int32 width, int32 height) const {
ImagePtr thumb = content_thumb(); const auto thumb = content_thumb();
const auto origin = fileOrigin();
if (thumb->loaded()) { if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int32 w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1); int32 w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1);
@ -675,10 +668,10 @@ void Video::prepareThumb(int32 width, int32 height) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
@ -971,7 +964,7 @@ TextState Contact::getState(
} }
void Contact::prepareThumb(int width, int height) const { void Contact::prepareThumb(int width, int height) const {
ImagePtr thumb = getResultThumb(); const auto thumb = getResultThumb();
if (thumb->isNull()) { if (thumb->isNull()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = getResultContactAvatar(width, height); _thumb = getResultContactAvatar(width, height);
@ -979,6 +972,7 @@ void Contact::prepareThumb(int width, int height) const {
return; return;
} }
const auto origin = fileOrigin();
if (thumb->loaded()) { if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1); int w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1);
@ -993,10 +987,10 @@ void Contact::prepareThumb(int width, int height) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
@ -1118,7 +1112,7 @@ TextState Article::getState(
} }
void Article::prepareThumb(int width, int height) const { void Article::prepareThumb(int width, int height) const {
ImagePtr thumb = getResultThumb(); const auto thumb = getResultThumb();
if (thumb->isNull()) { if (thumb->isNull()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = getResultContactAvatar(width, height); _thumb = getResultContactAvatar(width, height);
@ -1126,6 +1120,7 @@ void Article::prepareThumb(int width, int height) const {
return; return;
} }
const auto origin = fileOrigin();
if (thumb->loaded()) { if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1); int w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1);
@ -1140,10 +1135,10 @@ void Article::prepareThumb(int width, int height) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }
@ -1217,7 +1212,7 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
auto document = getResultDocument(); auto document = getResultDocument();
auto animatedThumb = document && document->isAnimation(); auto animatedThumb = document && document->isAnimation();
if (animatedThumb) { if (animatedThumb) {
document->automaticLoad(nullptr); document->automaticLoad(fileOrigin(), nullptr);
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading(); bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
if (loaded && !_gif && !_gif.isBad()) { if (loaded && !_gif && !_gif.isBad()) {
@ -1293,7 +1288,7 @@ TextState Game::getState(
} }
void Game::prepareThumb(int width, int height) const { void Game::prepareThumb(int width, int height) const {
auto thumb = [this] { const auto thumb = [this] {
if (auto photo = getResultPhoto()) { if (auto photo = getResultPhoto()) {
return photo->medium; return photo->medium;
} else if (auto document = getResultDocument()) { } else if (auto document = getResultDocument()) {
@ -1305,6 +1300,7 @@ void Game::prepareThumb(int width, int height) const {
return; return;
} }
const auto origin = fileOrigin();
if (thumb->loaded()) { if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) { if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1); int w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1);
@ -1321,10 +1317,10 @@ void Game::prepareThumb(int width, int height) const {
w = width; w = width;
} }
} }
_thumb = thumb->pixNoCache(w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height); _thumb = thumb->pixNoCache(origin, w * cIntRetinaFactor(), h * cIntRetinaFactor(), Images::Option::Smooth, width, height);
} }
} else { } else {
thumb->load(); thumb->load(origin);
} }
} }

View file

@ -68,18 +68,19 @@ PhotoData *ItemBase::getPreviewPhoto() const {
} }
void ItemBase::preload() const { void ItemBase::preload() const {
const auto origin = fileOrigin();
if (_result) { if (_result) {
if (_result->_photo) { if (_result->_photo) {
_result->_photo->thumb->load(); _result->_photo->thumb->load(origin);
} else if (_result->_document) { } else if (_result->_document) {
_result->_document->thumb->load(); _result->_document->thumb->load(origin);
} else if (!_result->_thumb->isNull()) { } else if (!_result->_thumb->isNull()) {
_result->_thumb->load(); _result->_thumb->load(origin);
} }
} else if (_doc) { } else if (_doc) {
_doc->thumb->load(); _doc->thumb->load(origin);
} else if (_photo) { } else if (_photo) {
_photo->medium->load(); _photo->medium->load(origin);
} }
} }

View file

@ -38,6 +38,7 @@ public:
virtual void inlineItemLayoutChanged(const ItemBase *layout) = 0; virtual void inlineItemLayoutChanged(const ItemBase *layout) = 0;
virtual bool inlineItemVisible(const ItemBase *item) = 0; virtual bool inlineItemVisible(const ItemBase *item) = 0;
virtual void inlineItemRepaint(const ItemBase *item) = 0; virtual void inlineItemRepaint(const ItemBase *item) = 0;
virtual Data::FileOrigin inlineItemFileOrigin() = 0;
}; };
class ItemBase : public LayoutItemBase { class ItemBase : public LayoutItemBase {
@ -105,6 +106,9 @@ protected:
not_null<Context*> context() const { not_null<Context*> context() const {
return _context; return _context;
} }
Data::FileOrigin fileOrigin() const {
return _context->inlineItemFileOrigin();
}
Result *_result = nullptr; Result *_result = nullptr;
DocumentData *_doc = nullptr; DocumentData *_doc = nullptr;

View file

@ -243,8 +243,8 @@ bool Result::onChoose(Layout::ItemBase *layout) {
if (_photo->medium->loaded() || _photo->thumb->loaded()) { if (_photo->medium->loaded() || _photo->thumb->loaded()) {
return true; return true;
} else if (!_photo->medium->loading()) { } else if (!_photo->medium->loading()) {
_photo->thumb->loadEvenCancelled(); _photo->thumb->loadEvenCancelled(Data::FileOrigin());
_photo->medium->loadEvenCancelled(); _photo->medium->loadEvenCancelled(Data::FileOrigin());
} }
return false; return false;
} }
@ -260,7 +260,11 @@ bool Result::onChoose(Layout::ItemBase *layout) {
} else if (_document->loading()) { } else if (_document->loading()) {
_document->cancel(); _document->cancel();
} else { } else {
DocumentOpenClickHandler::doOpen(_document, nullptr, ActionOnLoadNone); DocumentOpenClickHandler::Open(
Data::FileOriginSavedGifs(),
_document,
nullptr,
ActionOnLoadNone);
} }
return false; return false;
} }

View file

@ -593,6 +593,10 @@ bool Inner::inlineItemVisible(const ItemBase *layout) {
return (top < _visibleBottom) && (top + _rows[row].items[col]->height() > _visibleTop); return (top < _visibleBottom) && (top + _rows[row].items[col]->height() > _visibleTop);
} }
Data::FileOrigin Inner::inlineItemFileOrigin() {
return Data::FileOrigin();
}
void Inner::updateSelected() { void Inner::updateSelected() {
if (_pressed >= 0 && !_previewShown) { if (_pressed >= 0 && !_previewShown) {
return; return;
@ -662,10 +666,12 @@ void Inner::updateSelected() {
_pressed = _selected; _pressed = _selected;
if (row >= 0 && col >= 0) { if (row >= 0 && col >= 0) {
auto layout = _rows.at(row).items.at(col); auto layout = _rows.at(row).items.at(col);
if (auto previewDocument = layout->getPreviewDocument()) { if (const auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(previewDocument); Ui::showMediaPreview(
Data::FileOrigin(),
previewDocument);
} else if (auto previewPhoto = layout->getPreviewPhoto()) { } else if (auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(previewPhoto); Ui::showMediaPreview(Data::FileOrigin(), previewPhoto);
} }
} }
} }
@ -681,11 +687,11 @@ void Inner::onPreview() {
int row = _pressed / MatrixRowShift, col = _pressed % MatrixRowShift; int row = _pressed / MatrixRowShift, col = _pressed % MatrixRowShift;
if (row < _rows.size() && col < _rows.at(row).items.size()) { if (row < _rows.size() && col < _rows.at(row).items.size()) {
auto layout = _rows.at(row).items.at(col); auto layout = _rows.at(row).items.at(col);
if (auto previewDocument = layout->getPreviewDocument()) { if (const auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(previewDocument); Ui::showMediaPreview(Data::FileOrigin(), previewDocument);
_previewShown = true; _previewShown = true;
} else if (auto previewPhoto = layout->getPreviewPhoto()) { } else if (const auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(previewPhoto); Ui::showMediaPreview(Data::FileOrigin(), previewPhoto);
_previewShown = true; _previewShown = true;
} }
} }

View file

@ -66,6 +66,7 @@ public:
void inlineItemLayoutChanged(const ItemBase *layout) override; void inlineItemLayoutChanged(const ItemBase *layout) override;
void inlineItemRepaint(const ItemBase *layout) override; void inlineItemRepaint(const ItemBase *layout) override;
bool inlineItemVisible(const ItemBase *layout) override; bool inlineItemVisible(const ItemBase *layout) override;
Data::FileOrigin inlineItemFileOrigin() override;
int countHeight(); int countHeight();

View file

@ -1638,10 +1638,13 @@ void MainWidget::documentLoadFailed(FileLoader *loader, bool started) {
auto document = Auth().data().document(documentId); auto document = Auth().data().document(documentId);
if (started) { if (started) {
auto failedFileName = loader->fileName(); const auto origin = loader->fileOrigin();
const auto failedFileName = loader->fileName();
Ui::show(Box<ConfirmBox>(lang(lng_download_finish_failed), crl::guard(this, [=] { Ui::show(Box<ConfirmBox>(lang(lng_download_finish_failed), crl::guard(this, [=] {
Ui::hideLayer(); Ui::hideLayer();
if (document) document->save(failedFileName); if (document) {
document->save(origin, failedFileName);
}
}))); })));
} else { } else {
// Sometimes we have LOCATION_INVALID error in documents / stickers. // Sometimes we have LOCATION_INVALID error in documents / stickers.
@ -1790,7 +1793,7 @@ void MainWidget::updateScrollColors() {
void MainWidget::setChatBackground(const App::WallPaper &wp) { void MainWidget::setChatBackground(const App::WallPaper &wp) {
_background = std::make_unique<App::WallPaper>(wp); _background = std::make_unique<App::WallPaper>(wp);
_background->full->loadEvenCancelled(); _background->full->loadEvenCancelled(Data::FileOrigin());
checkChatBackground(); checkChatBackground();
} }
@ -1815,7 +1818,7 @@ void MainWidget::checkChatBackground() {
|| _background->id == Window::Theme::kDefaultBackground) { || _background->id == Window::Theme::kDefaultBackground) {
Window::Theme::Background()->setImage(_background->id); Window::Theme::Background()->setImage(_background->id);
} else { } else {
Window::Theme::Background()->setImage(_background->id, _background->full->pix().toImage()); Window::Theme::Background()->setImage(_background->id, _background->full->pix(Data::FileOrigin()).toImage());
} }
_background = nullptr; _background = nullptr;
QTimer::singleShot(0, this, SLOT(update())); QTimer::singleShot(0, this, SLOT(update()));

View file

@ -395,7 +395,9 @@ bool MainWindow::ui_isLayerShown() {
return _layer != nullptr; return _layer != nullptr;
} }
void MainWindow::ui_showMediaPreview(DocumentData *document) { void MainWindow::ui_showMediaPreview(
Data::FileOrigin origin,
not_null<DocumentData*> document) {
if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) { if (!document || ((!document->isAnimation() || !document->loaded()) && !document->sticker())) {
return; return;
} }
@ -406,11 +408,15 @@ void MainWindow::ui_showMediaPreview(DocumentData *document) {
if (_mediaPreview->isHidden()) { if (_mediaPreview->isHidden()) {
fixOrder(); fixOrder();
} }
_mediaPreview->showPreview(document); _mediaPreview->showPreview(origin, document);
} }
void MainWindow::ui_showMediaPreview(PhotoData *photo) { void MainWindow::ui_showMediaPreview(
if (!photo) return; Data::FileOrigin origin,
not_null<PhotoData*> photo) {
if (!photo) {
return;
}
if (!_mediaPreview) { if (!_mediaPreview) {
_mediaPreview.create(bodyWidget(), controller()); _mediaPreview.create(bodyWidget(), controller());
updateControlsGeometry(); updateControlsGeometry();
@ -418,7 +424,7 @@ void MainWindow::ui_showMediaPreview(PhotoData *photo) {
if (_mediaPreview->isHidden()) { if (_mediaPreview->isHidden()) {
fixOrder(); fixOrder();
} }
_mediaPreview->showPreview(photo); _mediaPreview->showPreview(origin, photo);
} }
void MainWindow::ui_hideMediaPreview() { void MainWindow::ui_hideMediaPreview() {

View file

@ -112,8 +112,12 @@ public:
anim::type animated); anim::type animated);
void ui_hideSettingsAndLayer(anim::type animated); void ui_hideSettingsAndLayer(anim::type animated);
bool ui_isLayerShown(); bool ui_isLayerShown();
void ui_showMediaPreview(DocumentData *document); void ui_showMediaPreview(
void ui_showMediaPreview(PhotoData *photo); Data::FileOrigin origin,
not_null<DocumentData*> document);
void ui_showMediaPreview(
Data::FileOrigin origin,
not_null<PhotoData*> photo);
void ui_hideMediaPreview(); void ui_hideMediaPreview();
protected: protected:

View file

@ -710,7 +710,10 @@ void Mixer::play(
} }
if (notLoadedYet) { if (notLoadedYet) {
if (type == AudioMsgId::Type::Song || type == AudioMsgId::Type::Video) { if (type == AudioMsgId::Type::Song || type == AudioMsgId::Type::Video) {
DocumentOpenClickHandler::doOpen(audio.audio(), App::histItemById(audio.contextId())); DocumentOpenClickHandler::Open(
audio.contextId(),
audio.audio(),
App::histItemById(audio.contextId()));
} else { } else {
onError(audio); onError(audio);
} }

View file

@ -238,7 +238,8 @@ bool Instance::moveInPlaylist(
|| document->isVideoMessage()) { || document->isVideoMessage()) {
play(AudioMsgId(document, item->fullId())); play(AudioMsgId(document, item->fullId()));
} else { } else {
//DocumentOpenClickHandler::doOpen( //DocumentOpenClickHandler::Open(
// item->fullId(),
// document, // document,
// item, // item,
// ActionOnLoadPlayInline); // ActionOnLoadPlayInline);
@ -440,9 +441,10 @@ void Instance::preloadNext(not_null<Data*> data) {
const auto isLoaded = document->loaded( const auto isLoaded = document->loaded(
DocumentData::FilePathResolveSaveFromDataSilent); DocumentData::FilePathResolveSaveFromDataSilent);
if (!isLoaded) { if (!isLoaded) {
DocumentOpenClickHandler::doOpen( DocumentOpenClickHandler::Open(
item->fullId(),
document, document,
nullptr, item,
ActionOnLoadNone); ActionOnLoadNone);
} }
} }

View file

@ -31,6 +31,20 @@ int Round(float64 value) {
using Context = GroupThumbs::Context; using Context = GroupThumbs::Context;
using Key = GroupThumbs::Key; using Key = GroupThumbs::Key;
Data::FileOrigin ComputeFileOrigin(const Key &key, const Context &context) {
return key.match([&](PhotoId photoId) {
return context.match([&](PeerId peerId) {
return peerIsUser(peerId)
? Data::FileOriginUserPhoto(peerToUser(peerId), photoId)
: Data::FileOrigin(Data::FileOriginPeerPhoto(peerId));
}, [&](auto&&) {
return Data::FileOrigin();
});
}, [](FullMsgId itemId) {
return Data::FileOrigin(itemId);
});
}
Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) { Context ComputeContext(const SharedMediaWithLastSlice &slice, int index) {
Expects(index >= 0 && index < slice.size()); Expects(index >= 0 && index < slice.size());
@ -96,7 +110,11 @@ public:
Dying, Dying,
}; };
Thumb(Key key, ImagePtr image, Fn<void()> handler); Thumb(
Key key,
ImagePtr image,
Data::FileOrigin origin,
Fn<void()> handler);
int leftToUpdate() const; int leftToUpdate() const;
int rightToUpdate() const; int rightToUpdate() const;
@ -123,6 +141,7 @@ private:
ClickHandlerPtr _link; ClickHandlerPtr _link;
const Key _key; const Key _key;
ImagePtr _image; ImagePtr _image;
Data::FileOrigin _origin;
State _state = State::Alive; State _state = State::Alive;
QPixmap _full; QPixmap _full;
int _fullWidth = 0; int _fullWidth = 0;
@ -137,9 +156,11 @@ private:
GroupThumbs::Thumb::Thumb( GroupThumbs::Thumb::Thumb(
Key key, Key key,
ImagePtr image, ImagePtr image,
Data::FileOrigin origin,
Fn<void()> handler) Fn<void()> handler)
: _key(key) : _key(key)
, _image(image) { , _image(image)
, _origin(origin) {
_link = std::make_shared<LambdaClickHandler>(std::move(handler)); _link = std::make_shared<LambdaClickHandler>(std::move(handler));
_fullWidth = std::min( _fullWidth = std::min(
wantedPixSize().width(), wantedPixSize().width(),
@ -159,7 +180,7 @@ void GroupThumbs::Thumb::validateImage() {
if (!_full.isNull()) { if (!_full.isNull()) {
return; return;
} }
_image->load(); _image->load(_origin);
if (!_image->loaded()) { if (!_image->loaded()) {
return; return;
} }
@ -170,7 +191,7 @@ void GroupThumbs::Thumb::validateImage() {
const auto originalHeight = _image->height(); const auto originalHeight = _image->height();
const auto takeWidth = originalWidth * st::mediaviewGroupWidthMax const auto takeWidth = originalWidth * st::mediaviewGroupWidthMax
/ pixSize.width(); / pixSize.width();
const auto original = _image->pixNoCache().toImage(); const auto original = _image->pixNoCache(_origin).toImage();
_full = App::pixmapFromImageInPlace(original.copy( _full = App::pixmapFromImageInPlace(original.copy(
(originalWidth - takeWidth) / 2, (originalWidth - takeWidth) / 2,
0, 0,
@ -183,6 +204,7 @@ void GroupThumbs::Thumb::validateImage() {
Qt::SmoothTransformation)); Qt::SmoothTransformation));
} else { } else {
_full = _image->pixNoCache( _full = _image->pixNoCache(
_origin,
pixSize.width() * cIntRetinaFactor(), pixSize.width() * cIntRetinaFactor(),
pixSize.height() * cIntRetinaFactor(), pixSize.height() * cIntRetinaFactor(),
Images::Option::Smooth); Images::Option::Smooth);
@ -396,7 +418,6 @@ void GroupThumbs::fillItems(
Expects(index < till); Expects(index < till);
Expects(from + 1 < till); Expects(from + 1 < till);
const auto current = (index - from); const auto current = (index - from);
const auto old = base::take(_items); const auto old = base::take(_items);
@ -470,10 +491,13 @@ void GroupThumbs::animatePreviouslyAlive(
} }
} }
auto GroupThumbs::createThumb(Key key) -> std::unique_ptr<Thumb> { auto GroupThumbs::createThumb(Key key)
-> std::unique_ptr<Thumb> {
if (const auto photoId = base::get_if<PhotoId>(&key)) { if (const auto photoId = base::get_if<PhotoId>(&key)) {
const auto photo = Auth().data().photo(*photoId); const auto photo = Auth().data().photo(*photoId);
return createThumb(key, photo->date ? photo->thumb : ImagePtr()); return createThumb(
key,
photo->date ? photo->thumb : ImagePtr());
} else if (const auto msgId = base::get_if<FullMsgId>(&key)) { } else if (const auto msgId = base::get_if<FullMsgId>(&key)) {
if (const auto item = App::histItemById(*msgId)) { if (const auto item = App::histItemById(*msgId)) {
if (const auto media = item->media()) { if (const auto media = item->media()) {
@ -492,7 +516,8 @@ auto GroupThumbs::createThumb(Key key) -> std::unique_ptr<Thumb> {
auto GroupThumbs::createThumb(Key key, ImagePtr image) auto GroupThumbs::createThumb(Key key, ImagePtr image)
-> std::unique_ptr<Thumb> { -> std::unique_ptr<Thumb> {
const auto weak = base::make_weak(this); const auto weak = base::make_weak(this);
return std::make_unique<Thumb>(key, image, [=] { const auto origin = ComputeFileOrigin(key, _context);
return std::make_unique<Thumb>(key, image, origin, [=] {
if (const auto strong = weak.get()) { if (const auto strong = weak.get()) {
strong->_activateStream.fire_copy(key); strong->_activateStream.fire_copy(key);
} }

View file

@ -843,7 +843,7 @@ void MediaView::onSaveAs() {
if (_doc->data().isEmpty()) location.accessDisable(); if (_doc->data().isEmpty()) location.accessDisable();
} else { } else {
if (!fileShown()) { if (!fileShown()) {
DocumentSaveClickHandler::doSave(_doc, true); DocumentSaveClickHandler::Save(fileOrigin(), _doc, true);
updateControls(); updateControls();
} else { } else {
_saveVisible = false; _saveVisible = false;
@ -868,7 +868,7 @@ void MediaView::onSaveAs() {
_photo->date), _photo->date),
crl::guard(this, [this, photo = _photo](const QString &result) { crl::guard(this, [this, photo = _photo](const QString &result) {
if (!result.isEmpty() && _photo == photo && photo->loaded()) { if (!result.isEmpty() && _photo == photo && photo->loaded()) {
photo->full->pix().toImage().save(result, "JPG"); photo->full->pix(fileOrigin()).toImage().save(result, "JPG");
} }
psShowOverAll(this); psShowOverAll(this);
}), crl::guard(this, [this] { }), crl::guard(this, [this] {
@ -884,7 +884,11 @@ void MediaView::onDocClick() {
if (_doc->loading()) { if (_doc->loading()) {
onSaveCancel(); onSaveCancel();
} else { } else {
DocumentOpenClickHandler::doOpen(_doc, nullptr, ActionOnLoadNone); DocumentOpenClickHandler::Open(
fileOrigin(),
_doc,
App::histItemById(_msgid),
ActionOnLoadNone);
if (_doc->loading() && !_radial.animating()) { if (_doc->loading() && !_radial.animating()) {
_radial.start(_doc->progress()); _radial.start(_doc->progress());
} }
@ -971,7 +975,7 @@ void MediaView::onDownload() {
location.accessDisable(); location.accessDisable();
} else { } else {
if (!fileShown()) { if (!fileShown()) {
DocumentSaveClickHandler::doSave(_doc); DocumentSaveClickHandler::Save(fileOrigin(), _doc);
updateControls(); updateControls();
} else { } else {
_saveVisible = false; _saveVisible = false;
@ -986,7 +990,7 @@ void MediaView::onDownload() {
} else { } else {
if (!QDir().exists(path)) QDir().mkpath(path); if (!QDir().exists(path)) QDir().mkpath(path);
toName = filedialogDefaultName(qsl("photo"), qsl(".jpg"), path); toName = filedialogDefaultName(qsl("photo"), qsl(".jpg"), path);
if (!_photo->full->pix().toImage().save(toName, "JPG")) { if (!_photo->full->pix(fileOrigin()).toImage().save(toName, "JPG")) {
toName = QString(); toName = QString();
} }
} }
@ -1065,7 +1069,7 @@ void MediaView::onCopy() {
} else { } else {
if (!_photo || !_photo->loaded()) return; if (!_photo || !_photo->loaded()) return;
QApplication::clipboard()->setPixmap(_photo->full->pix()); QApplication::clipboard()->setPixmap(_photo->full->pix(fileOrigin()));
} }
} }
@ -1113,6 +1117,17 @@ base::optional<MediaView::SharedMediaKey> MediaView::sharedMediaKey() const {
| keyForType; | keyForType;
} }
Data::FileOrigin MediaView::fileOrigin() const {
if (_msgid) {
return _msgid;
} else if (_photo && _user) {
return Data::FileOriginUserPhoto(_user->bareId(), _photo->id);
} else if (_photo && _peer && _peer->userpicPhotoId() == _photo->id) {
return Data::FileOriginPeerPhoto(_peer->id);
}
return Data::FileOrigin();
}
bool MediaView::validSharedMedia() const { bool MediaView::validSharedMedia() const {
if (auto key = sharedMediaKey()) { if (auto key = sharedMediaKey()) {
if (!_sharedMedia) { if (!_sharedMedia) {
@ -1452,7 +1467,7 @@ void MediaView::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item) {
} else { } else {
_from = _user; _from = _user;
} }
_photo->download(); _photo->download(fileOrigin());
displayFinished(); displayFinished();
} }
@ -1493,12 +1508,15 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (_doc->sticker()) { if (_doc->sticker()) {
_doc->checkSticker(); _doc->checkSticker();
if (!_doc->sticker()->img->isNull()) { if (!_doc->sticker()->img->isNull()) {
_current = _doc->sticker()->img->pix(); _current = _doc->sticker()->img->pix(fileOrigin());
} else { } else {
_current = _doc->thumb->pixBlurred(_doc->dimensions.width(), _doc->dimensions.height()); _current = _doc->thumb->pixBlurred(
fileOrigin(),
_doc->dimensions.width(),
_doc->dimensions.height());
} }
} else { } else {
_doc->automaticLoad(item); _doc->automaticLoad(fileOrigin(), item);
if (_doc->isAnimation() || _doc->isVideoFile()) { if (_doc->isAnimation() || _doc->isVideoFile()) {
initAnimation(); initAnimation();
@ -1531,7 +1549,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
_docExtWidth = st::mediaviewFileNameFont->width(_docExt); _docExtWidth = st::mediaviewFileNameFont->width(_docExt);
} }
} else { } else {
_doc->thumb->load(); _doc->thumb->load(fileOrigin());
int32 tw = _doc->thumb->width(), th = _doc->thumb->height(); int32 tw = _doc->thumb->width(), th = _doc->thumb->height();
if (!tw || !th) { if (!tw || !th) {
_docThumbx = _docThumby = _docThumbw = 0; _docThumbx = _docThumby = _docThumbw = 0;
@ -1673,10 +1691,10 @@ void MediaView::initAnimation() {
} else if (_doc->dimensions.width() && _doc->dimensions.height()) { } else if (_doc->dimensions.width() && _doc->dimensions.height()) {
auto w = _doc->dimensions.width(); auto w = _doc->dimensions.width();
auto h = _doc->dimensions.height(); auto h = _doc->dimensions.height();
_current = _doc->thumb->pixNoCache(w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor()); _current = _doc->thumb->pixNoCache(fileOrigin(), w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor());
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
} else { } else {
_current = _doc->thumb->pixNoCache(_doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize); _current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
} }
} }
@ -1689,10 +1707,10 @@ void MediaView::createClipReader() {
if (_doc->dimensions.width() && _doc->dimensions.height()) { if (_doc->dimensions.width() && _doc->dimensions.height()) {
int w = _doc->dimensions.width(); int w = _doc->dimensions.width();
int h = _doc->dimensions.height(); int h = _doc->dimensions.height();
_current = _doc->thumb->pixNoCache(w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor()); _current = _doc->thumb->pixNoCache(fileOrigin(), w, h, videoThumbOptions(), w / cIntRetinaFactor(), h / cIntRetinaFactor());
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
} else { } else {
_current = _doc->thumb->pixNoCache(_doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize); _current = _doc->thumb->pixNoCache(fileOrigin(), _doc->thumb->width(), _doc->thumb->height(), videoThumbOptions(), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
} }
auto mode = (_doc->isVideoFile() || _doc->isVideoMessage()) auto mode = (_doc->isVideoFile() || _doc->isVideoMessage())
? Media::Clip::Reader::Mode::Video ? Media::Clip::Reader::Mode::Video
@ -1957,20 +1975,20 @@ void MediaView::paintEvent(QPaintEvent *e) {
int32 w = _width * cIntRetinaFactor(); int32 w = _width * cIntRetinaFactor();
if (_full <= 0 && _photo->loaded()) { if (_full <= 0 && _photo->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999); int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->full->pixNoCache(w, h, Images::Option::Smooth); _current = _photo->full->pixNoCache(fileOrigin(), w, h, Images::Option::Smooth);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_full = 1; _full = 1;
} else if (_full < 0 && _photo->medium->loaded()) { } else if (_full < 0 && _photo->medium->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999); int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->medium->pixNoCache(w, h, Images::Option::Smooth | Images::Option::Blurred); _current = _photo->medium->pixNoCache(fileOrigin(), w, h, Images::Option::Smooth | Images::Option::Blurred);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
_full = 0; _full = 0;
} else if (_current.isNull() && _photo->thumb->loaded()) { } else if (_current.isNull() && _photo->thumb->loaded()) {
int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999); int32 h = int((_photo->full->height() * (qreal(w) / qreal(_photo->full->width()))) + 0.9999);
_current = _photo->thumb->pixNoCache(w, h, Images::Option::Smooth | Images::Option::Blurred); _current = _photo->thumb->pixNoCache(fileOrigin(), w, h, Images::Option::Smooth | Images::Option::Blurred);
if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) _current.setDevicePixelRatio(cRetinaFactor());
} else if (_current.isNull()) { } else if (_current.isNull()) {
_current = _photo->thumb->pix(); _current = _photo->thumb->pix(fileOrigin());
} }
} }
p.setOpacity(1); p.setOpacity(1);
@ -2071,7 +2089,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
} }
} else { } else {
int32 rf(cIntRetinaFactor()); int32 rf(cIntRetinaFactor());
p.drawPixmap(_docIconRect.topLeft(), _doc->thumb->pix(_docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mediaviewFileIconSize * rf, st::mediaviewFileIconSize * rf)); p.drawPixmap(_docIconRect.topLeft(), _doc->thumb->pix(fileOrigin(), _docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mediaviewFileIconSize * rf, st::mediaviewFileIconSize * rf));
} }
paintDocRadialLoading(p, radial, radialOpacity); paintDocRadialLoading(p, radial, radialOpacity);
@ -2571,13 +2589,13 @@ void MediaView::preloadData(int delta) {
for (auto index = from; index != till; ++index) { for (auto index = from; index != till; ++index) {
auto entity = entityByIndex(index); auto entity = entityByIndex(index);
if (auto photo = base::get_if<not_null<PhotoData*>>(&entity.data)) { if (auto photo = base::get_if<not_null<PhotoData*>>(&entity.data)) {
(*photo)->download(); (*photo)->download(fileOrigin());
} else if (auto document = base::get_if<not_null<DocumentData*>>(&entity.data)) { } else if (auto document = base::get_if<not_null<DocumentData*>>(&entity.data)) {
if (auto sticker = (*document)->sticker()) { if (auto sticker = (*document)->sticker()) {
sticker->img->load(); sticker->img->load(fileOrigin());
} else { } else {
(*document)->thumb->load(); (*document)->thumb->load(fileOrigin());
(*document)->automaticLoad(entity.item); (*document)->automaticLoad(fileOrigin(), entity.item);
} }
} }
} }

View file

@ -175,6 +175,8 @@ private:
void validateUserPhotos(); void validateUserPhotos();
void handleUserPhotosUpdate(UserPhotosSlice &&update); void handleUserPhotosUpdate(UserPhotosSlice &&update);
Data::FileOrigin fileOrigin() const;
void refreshCaption(HistoryItem *item); void refreshCaption(HistoryItem *item);
void refreshMediaViewer(); void refreshMediaViewer();
void refreshNavVisibility(); void refreshNavVisibility();

View file

@ -314,7 +314,7 @@ int32 Photo::resizeGetHeight(int32 width) {
void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
bool good = _data->loaded(), selected = (selection == FullSelection); bool good = _data->loaded(), selected = (selection == FullSelection);
if (!good) { if (!good) {
_data->medium->automaticLoad(parent()); _data->medium->automaticLoad(parent()->fullId(), parent());
good = _data->medium->loaded(); good = _data->medium->loaded();
} }
if ((good && !_goodLoaded) || _pix.width() != _width * cIntRetinaFactor()) { if ((good && !_goodLoaded) || _pix.width() != _width * cIntRetinaFactor()) {
@ -322,7 +322,7 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
int32 size = _width * cIntRetinaFactor(); int32 size = _width * cIntRetinaFactor();
if (_goodLoaded || _data->thumb->loaded()) { if (_goodLoaded || _data->thumb->loaded()) {
auto img = (_data->loaded() ? _data->full : (_data->medium->loaded() ? _data->medium : _data->thumb))->pix().toImage(); auto img = (_data->loaded() ? _data->full : (_data->medium->loaded() ? _data->medium : _data->thumb))->pix(parent()->fullId()).toImage();
if (!_goodLoaded) { if (!_goodLoaded) {
img = Images::prepareBlur(std::move(img)); img = Images::prepareBlur(std::move(img));
} }
@ -376,7 +376,7 @@ Video::Video(
, _duration(formatDurationText(_data->duration())) , _duration(formatDurationText(_data->duration()))
, _thumbLoaded(false) { , _thumbLoaded(false) {
setDocumentLinks(_data); setDocumentLinks(_data);
_data->thumb->load(); _data->thumb->load(parent->fullId());
} }
void Video::initDimensions() { void Video::initDimensions() {
@ -393,7 +393,7 @@ int32 Video::resizeGetHeight(int32 width) {
void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded(); bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded();
_data->automaticLoad(parent()); _data->automaticLoad(parent()->fullId(), parent());
bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
if (displayLoading) { if (displayLoading) {
ensureRadial(); ensureRadial();
@ -409,7 +409,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
if (_thumbLoaded && !_data->thumb->isNull()) { if (_thumbLoaded && !_data->thumb->isNull()) {
auto size = _width * cIntRetinaFactor(); auto size = _width * cIntRetinaFactor();
auto img = Images::prepareBlur(_data->thumb->pix().toImage()); auto img = Images::prepareBlur(_data->thumb->pix(parent()->fullId()).toImage());
if (img.width() == img.height()) { if (img.width() == img.height()) {
if (img.width() != size) { if (img.width() != size) {
img = img.scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); img = img.scaled(size, size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
@ -594,7 +594,7 @@ void Voice::initDimensions() {
void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
bool selected = (selection == FullSelection); bool selected = (selection == FullSelection);
_data->automaticLoad(parent()); _data->automaticLoad(parent()->fullId(), parent());
bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
if (displayLoading) { if (displayLoading) {
@ -832,7 +832,7 @@ Document::Document(
_status.update(FileStatusSizeReady, _data->size, _data->isSong() ? _data->song()->duration : -1, 0); _status.update(FileStatusSizeReady, _data->size, _data->isSong() ? _data->song()->duration : -1, 0);
if (withThumb()) { if (withThumb()) {
_data->thumb->load(); _data->thumb->load(parent->fullId());
int32 tw = convertScale(_data->thumb->width()), th = convertScale(_data->thumb->height()); int32 tw = convertScale(_data->thumb->width()), th = convertScale(_data->thumb->height());
if (tw > th) { if (tw > th) {
_thumbw = (tw * _st.fileThumbSize) / th; _thumbw = (tw * _st.fileThumbSize) / th;
@ -862,7 +862,7 @@ void Document::initDimensions() {
void Document::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) { void Document::paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) {
bool selected = (selection == FullSelection); bool selected = (selection == FullSelection);
_data->automaticLoad(parent()); _data->automaticLoad(parent()->fullId(), parent());
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()), displayLoading = _data->displayLoading(); bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()), displayLoading = _data->displayLoading();
if (displayLoading) { if (displayLoading) {
@ -936,7 +936,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
_thumbForLoaded = loaded; _thumbForLoaded = loaded;
auto options = Images::Option::Smooth | Images::Option::None; auto options = Images::Option::Smooth | Images::Option::None;
if (!_thumbForLoaded) options |= Images::Option::Blurred; if (!_thumbForLoaded) options |= Images::Option::Blurred;
_thumb = _data->thumb->pixNoCache(_thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize); _thumb = _data->thumb->pixNoCache(parent()->fullId(), _thumbw * cIntRetinaFactor(), 0, options, _st.fileThumbSize, _st.fileThumbSize);
} }
p.drawPixmap(rthumb.topLeft(), _thumb); p.drawPixmap(rthumb.topLeft(), _thumb);
} else { } else {
@ -1267,12 +1267,16 @@ Link::Link(
} }
int32 tw = 0, th = 0; int32 tw = 0, th = 0;
if (_page && _page->photo) { if (_page && _page->photo) {
if (!_page->photo->loaded()) _page->photo->thumb->load(false, false); if (!_page->photo->loaded()) {
_page->photo->thumb->load(parent->fullId(), false, false);
}
tw = convertScale(_page->photo->thumb->width()); tw = convertScale(_page->photo->thumb->width());
th = convertScale(_page->photo->thumb->height()); th = convertScale(_page->photo->thumb->height());
} else if (_page && _page->document) { } else if (_page && _page->document) {
if (!_page->document->thumb->loaded()) _page->document->thumb->load(false, false); if (!_page->document->thumb->loaded()) {
_page->document->thumb->load(parent->fullId(), false, false);
}
tw = convertScale(_page->document->thumb->width()); tw = convertScale(_page->document->thumb->width());
th = convertScale(_page->document->thumb->height()); th = convertScale(_page->document->thumb->height());
@ -1357,18 +1361,18 @@ void Link::paint(Painter &p, const QRect &clip, TextSelection selection, const P
if (_page && _page->photo) { if (_page && _page->photo) {
QPixmap pix; QPixmap pix;
if (_page->photo->medium->loaded()) { if (_page->photo->medium->loaded()) {
pix = _page->photo->medium->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); pix = _page->photo->medium->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} else if (_page->photo->loaded()) { } else if (_page->photo->loaded()) {
pix = _page->photo->full->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); pix = _page->photo->full->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} else { } else {
pix = _page->photo->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small); pix = _page->photo->thumb->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, ImageRoundRadius::Small);
} }
p.drawPixmapLeft(pixLeft, pixTop, _width, pix); p.drawPixmapLeft(pixLeft, pixTop, _width, pix);
} else if (_page && _page->document && !_page->document->thumb->isNull()) { } else if (_page && _page->document && !_page->document->thumb->isNull()) {
auto roundRadius = _page->document->isVideoMessage() auto roundRadius = _page->document->isVideoMessage()
? ImageRoundRadius::Ellipse ? ImageRoundRadius::Ellipse
: ImageRoundRadius::Small; : ImageRoundRadius::Small;
p.drawPixmapLeft(pixLeft, pixTop, _width, _page->document->thumb->pixSingle(_pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius)); p.drawPixmapLeft(pixLeft, pixTop, _width, _page->document->thumb->pixSingle(parent()->fullId(), _pixw, _pixh, st::linksPhotoSize, st::linksPhotoSize, roundRadius));
} else { } else {
const auto index = _letter.isEmpty() const auto index = _letter.isEmpty()
? 0 ? 0

View file

@ -1705,8 +1705,8 @@ void FormController::loadFile(File &file) {
file.dcId, file.dcId,
file.id, file.id,
file.accessHash, file.accessHash,
0, // version
QByteArray(), // file_reference QByteArray(), // file_reference
base::none, // origin
SecureFileLocation, SecureFileLocation,
QString(), QString(),
file.size, file.size,

View file

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/core_cloud_password.h" #include "core/core_cloud_password.h"
class BoxContent; class BoxContent;
class mtpFileLoader;
namespace Storage { namespace Storage {
struct UploadSecureDone; struct UploadSecureDone;

View file

@ -71,7 +71,7 @@ void BackgroundRow::paintEvent(QPaintEvent *e) {
if (backThumb->isNull()) { if (backThumb->isNull()) {
p.drawPixmap(0, 0, _background); p.drawPixmap(0, 0, _background);
} else { } else {
const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(st::settingsBackgroundSize); const QPixmap &pix = App::main()->newBackgroundThumb()->pixBlurred(Data::FileOrigin(), st::settingsBackgroundSize);
p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, 0, (pix.height() - st::settingsBackgroundSize * cIntRetinaFactor()) / 2, st::settingsBackgroundSize * cIntRetinaFactor(), st::settingsBackgroundSize * cIntRetinaFactor()); p.drawPixmap(0, 0, st::settingsBackgroundSize, st::settingsBackgroundSize, pix, 0, (pix.height() - st::settingsBackgroundSize * cIntRetinaFactor()) / 2, st::settingsBackgroundSize * cIntRetinaFactor(), st::settingsBackgroundSize * cIntRetinaFactor());
} }

View file

@ -395,6 +395,7 @@ void FileLoader::startLoading(bool loadFirst, bool prior) {
mtpFileLoader::mtpFileLoader( mtpFileLoader::mtpFileLoader(
const StorageImageLocation *location, const StorageImageLocation *location,
Data::FileOrigin origin,
int32 size, int32 size,
LoadFromCloudSetting fromCloud LoadFromCloudSetting fromCloud
, bool autoLoading) , bool autoLoading)
@ -406,7 +407,8 @@ mtpFileLoader::mtpFileLoader(
fromCloud, fromCloud,
autoLoading) autoLoading)
, _dcId(location->dc()) , _dcId(location->dc())
, _location(location) { , _location(location)
, _origin(origin) {
auto shiftedDcId = MTP::downloadDcId(_dcId, 0); auto shiftedDcId = MTP::downloadDcId(_dcId, 0);
auto i = queues.find(shiftedDcId); auto i = queues.find(shiftedDcId);
if (i == queues.cend()) { if (i == queues.cend()) {
@ -419,8 +421,8 @@ mtpFileLoader::mtpFileLoader(
int32 dc, int32 dc,
uint64 id, uint64 id,
uint64 accessHash, uint64 accessHash,
int32 version,
const QByteArray &fileReference, const QByteArray &fileReference,
Data::FileOrigin origin,
LocationType type, LocationType type,
const QString &to, const QString &to,
int32 size, int32 size,
@ -437,8 +439,8 @@ mtpFileLoader::mtpFileLoader(
, _dcId(dc) , _dcId(dc)
, _id(id) , _id(id)
, _accessHash(accessHash) , _accessHash(accessHash)
, _version(version) , _fileReference(fileReference)
, _fileReference(fileReference) { , _origin(origin) {
auto shiftedDcId = MTP::downloadDcId(_dcId, 0); auto shiftedDcId = MTP::downloadDcId(_dcId, 0);
auto i = queues.find(shiftedDcId); auto i = queues.find(shiftedDcId);
if (i == queues.cend()) { if (i == queues.cend()) {
@ -473,6 +475,10 @@ int32 mtpFileLoader::currentOffset(bool includeSkipped) const {
return (_fileIsOpen ? _file.size() : _data.size()) - (includeSkipped ? 0 : _skippedBytes); return (_fileIsOpen ? _file.size() : _data.size()) - (includeSkipped ? 0 : _skippedBytes);
} }
Data::FileOrigin mtpFileLoader::fileOrigin() const {
return _origin;
}
bool mtpFileLoader::loadPart() { bool mtpFileLoader::loadPart() {
if (_finished || _lastComplete || (!_sentRequests.empty() && !_size)) { if (_finished || _lastComplete || (!_sentRequests.empty() && !_size)) {
return false; return false;
@ -572,7 +578,6 @@ MTPInputFileLocation mtpFileLoader::computeLocation() const {
return MTP_inputDocumentFileLocation( return MTP_inputDocumentFileLocation(
MTP_long(_id), MTP_long(_id),
MTP_long(_accessHash), MTP_long(_accessHash),
MTP_int(_version),
MTP_bytes(_fileReference)); MTP_bytes(_fileReference));
} }
@ -843,7 +848,7 @@ bool mtpFileLoader::feedPart(int offset, bytes::const_span buffer) {
if (_urlLocation) { if (_urlLocation) {
Local::writeImage(storageKey(*_urlLocation), StorageImageSaved(_data)); Local::writeImage(storageKey(*_urlLocation), StorageImageSaved(_data));
} else if (_locationType != UnknownFileLocation) { // audio, video, document } else if (_locationType != UnknownFileLocation) { // audio, video, document
auto mkey = mediaKey(_locationType, _dcId, _id, _version); auto mkey = mediaKey(_locationType, _dcId, _id);
if (!_filename.isEmpty()) { if (!_filename.isEmpty()) {
Local::writeFileLocation(mkey, FileLocation(_filename)); Local::writeFileLocation(mkey, FileLocation(_filename));
} }
@ -998,7 +1003,7 @@ bool mtpFileLoader::tryLoadLocal() {
_localTaskId = Local::startImageLoad(storageKey(*_location), this); _localTaskId = Local::startImageLoad(storageKey(*_location), this);
} else { } else {
if (_toCache == LoadToCacheAsWell) { if (_toCache == LoadToCacheAsWell) {
MediaKey mkey = mediaKey(_locationType, _dcId, _id, _version); MediaKey mkey = mediaKey(_locationType, _dcId, _id);
if (_locationType == DocumentFileLocation) { if (_locationType == DocumentFileLocation) {
_localTaskId = Local::startStickerImageLoad(mkey, this); _localTaskId = Local::startStickerImageLoad(mkey, this);
} else if (_locationType == AudioFileLocation) { } else if (_locationType == AudioFileLocation) {

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/observer.h" #include "base/observer.h"
#include "storage/localimageloader.h" // for TaskId #include "storage/localimageloader.h" // for TaskId
#include "data/data_file_origin.h"
namespace Storage { namespace Storage {
@ -94,6 +95,9 @@ public:
QString fileName() const { QString fileName() const {
return _filename; return _filename;
} }
virtual Data::FileOrigin fileOrigin() const {
return Data::FileOrigin();
}
float64 currentProgress() const; float64 currentProgress() const;
virtual int32 currentOffset(bool includeSkipped = false) const = 0; virtual int32 currentOffset(bool includeSkipped = false) const = 0;
int32 fullSize() const; int32 fullSize() const;
@ -183,6 +187,7 @@ class mtpFileLoader : public FileLoader, public RPCSender {
public: public:
mtpFileLoader( mtpFileLoader(
const StorageImageLocation *location, const StorageImageLocation *location,
Data::FileOrigin origin,
int32 size, int32 size,
LoadFromCloudSetting fromCloud, LoadFromCloudSetting fromCloud,
bool autoLoading); bool autoLoading);
@ -190,8 +195,8 @@ public:
int32 dc, int32 dc,
uint64 id, uint64 id,
uint64 accessHash, uint64 accessHash,
int32 version,
const QByteArray &fileReference, const QByteArray &fileReference,
Data::FileOrigin origin,
LocationType type, LocationType type,
const QString &toFile, const QString &toFile,
int32 size, int32 size,
@ -205,6 +210,7 @@ public:
bool autoLoading); bool autoLoading);
int32 currentOffset(bool includeSkipped = false) const override; int32 currentOffset(bool includeSkipped = false) const override;
Data::FileOrigin fileOrigin() const override;
uint64 objId() const override { uint64 objId() const override {
return _id; return _id;
@ -275,11 +281,12 @@ private:
uint64 _id = 0; // for document locations uint64 _id = 0; // for document locations
uint64 _accessHash = 0; uint64 _accessHash = 0;
int32 _version = 0;
QByteArray _fileReference; QByteArray _fileReference;
const WebFileLocation *_urlLocation = nullptr; // for webdocument locations const WebFileLocation *_urlLocation = nullptr; // for webdocument locations
Data::FileOrigin _origin;
MTP::DcId _cdnDcId = 0; MTP::DcId _cdnDcId = 0;
QByteArray _cdnToken; QByteArray _cdnToken;
QByteArray _cdnEncryptionKey; QByteArray _cdnEncryptionKey;

View file

@ -618,7 +618,6 @@ void FileLoadTask::process() {
MTP_int(filesize), MTP_int(filesize),
thumbSize, thumbSize,
MTP_int(MTP::maindc()), MTP_int(MTP::maindc()),
MTP_int(0),
MTP_vector<MTPDocumentAttribute>(attributes)); MTP_vector<MTPDocumentAttribute>(attributes));
} else if (_type != SendMediaType::Photo) { } else if (_type != SendMediaType::Photo) {
document = MTP_document( document = MTP_document(
@ -630,7 +629,6 @@ void FileLoadTask::process() {
MTP_int(filesize), MTP_int(filesize),
thumbSize, thumbSize,
MTP_int(MTP::maindc()), MTP_int(MTP::maindc()),
MTP_int(0),
MTP_vector<MTPDocumentAttribute>(attributes)); MTP_vector<MTPDocumentAttribute>(attributes));
_type = SendMediaType::File; _type = SendMediaType::File;
} }

View file

@ -3949,7 +3949,6 @@ void importOldRecentStickers() {
const auto doc = Auth().data().document( const auto doc = Auth().data().document(
id, id,
access, access,
int32(0),
QByteArray(), QByteArray(),
date, date,
attributes, attributes,

View file

@ -29,7 +29,11 @@ StorageImageLocation readStorageImageLocation(
quint64 volume, secret; quint64 volume, secret;
QByteArray fileReference; QByteArray fileReference;
stream >> width >> height >> dc >> volume >> local >> secret; stream >> width >> height >> dc >> volume >> local >> secret;
if (streamAppVersion >= 1003011) { #ifdef _DEBUG
if (streamAppVersion >= 1003013 || true) { // #TODO testing
#else
#error "test"
#endif
stream >> fileReference; stream >> fileReference;
} }
return StorageImageLocation( return StorageImageLocation(

View file

@ -25,8 +25,9 @@ enum StickerSetType {
namespace Serialize { namespace Serialize {
void Document::writeToStream(QDataStream &stream, DocumentData *document) { void Document::writeToStream(QDataStream &stream, DocumentData *document) {
const auto version = 0;
stream << quint64(document->id) << quint64(document->_access) << qint32(document->date); stream << quint64(document->id) << quint64(document->_access) << qint32(document->date);
stream << document->_fileReference << qint32(document->_version); stream << document->_fileReference << qint32(version);
stream << document->filename() << document->mimeString() << qint32(document->_dc) << qint32(document->size); stream << document->filename() << document->mimeString() << qint32(document->_dc) << qint32(document->size);
stream << qint32(document->dimensions.width()) << qint32(document->dimensions.height()); stream << qint32(document->dimensions.width()) << qint32(document->dimensions.height());
stream << qint32(document->type); stream << qint32(document->type);
@ -58,7 +59,11 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream &
QByteArray fileReference; QByteArray fileReference;
stream >> id >> access >> date; stream >> id >> access >> date;
if (streamAppVersion >= 9061) { if (streamAppVersion >= 9061) {
if (streamAppVersion >= 1003011) { #ifdef _DEBUG
if (streamAppVersion >= 1003013 || true) { // #TODO testing
#else
#error "test"
#endif
stream >> fileReference; stream >> fileReference;
} }
stream >> version; stream >> version;
@ -131,7 +136,6 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream &
return Auth().data().document( return Auth().data().document(
id, id,
access, access,
version,
fileReference, fileReference,
date, date,
attributes, attributes,

View file

@ -477,7 +477,10 @@ Image::Image(const QByteArray &filecontent, QByteArray fmt, const QPixmap &pixma
} }
} }
const QPixmap &Image::pix(int32 w, int32 h) const { const QPixmap &Image::pix(
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -490,7 +493,7 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options); auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -500,7 +503,12 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
return i.value(); return i.value();
} }
const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, RectParts corners) const { const QPixmap &Image::pixRounded(
Data::FileOrigin origin,
int32 w,
int32 h,
ImageRoundRadius radius,
RectParts corners) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -526,7 +534,7 @@ const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, Rect
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options); auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -536,7 +544,10 @@ const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, Rect
return i.value(); return i.value();
} }
const QPixmap &Image::pixCircled(int32 w, int32 h) const { const QPixmap &Image::pixCircled(
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -549,7 +560,7 @@ const QPixmap &Image::pixCircled(int32 w, int32 h) const {
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options); auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -559,7 +570,10 @@ const QPixmap &Image::pixCircled(int32 w, int32 h) const {
return i.value(); return i.value();
} }
const QPixmap &Image::pixBlurredCircled(int32 w, int32 h) const { const QPixmap &Image::pixBlurredCircled(
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -572,7 +586,7 @@ const QPixmap &Image::pixBlurredCircled(int32 w, int32 h) const {
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options); auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -582,7 +596,10 @@ const QPixmap &Image::pixBlurredCircled(int32 w, int32 h) const {
return i.value(); return i.value();
} }
const QPixmap &Image::pixBlurred(int32 w, int32 h) const { const QPixmap &Image::pixBlurred(
Data::FileOrigin origin,
int32 w,
int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -595,7 +612,7 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options); auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -605,7 +622,11 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
return i.value(); return i.value();
} }
const QPixmap &Image::pixColored(style::color add, int32 w, int32 h) const { const QPixmap &Image::pixColored(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -618,7 +639,7 @@ const QPixmap &Image::pixColored(style::color add, int32 w, int32 h) const {
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixColoredNoCache(add, w, h, true); auto p = pixColoredNoCache(origin, add, w, h, true);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -628,7 +649,11 @@ const QPixmap &Image::pixColored(style::color add, int32 w, int32 h) const {
return i.value(); return i.value();
} }
const QPixmap &Image::pixBlurredColored(style::color add, int32 w, int32 h) const { const QPixmap &Image::pixBlurredColored(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -641,7 +666,7 @@ const QPixmap &Image::pixBlurredColored(style::color add, int32 w, int32 h) cons
auto k = PixKey(w, h, options); auto k = PixKey(w, h, options);
auto i = _sizesCache.constFind(k); auto i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) { if (i == _sizesCache.cend()) {
auto p = pixBlurredColoredNoCache(add, w, h); auto p = pixBlurredColoredNoCache(origin, add, w, h);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -651,7 +676,15 @@ const QPixmap &Image::pixBlurredColored(style::color add, int32 w, int32 h) cons
return i.value(); return i.value();
} }
const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, RectParts corners, const style::color *colored) const { const QPixmap &Image::pixSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners,
const style::color *colored) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -685,7 +718,7 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, Im
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
globalAcquiredSize -= int64(i->width()) * i->height() * 4; globalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
auto p = pixNoCache(w, h, options, outerw, outerh, colored); auto p = pixNoCache(origin, w, h, options, outerw, outerh, colored);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -695,7 +728,14 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, Im
return i.value(); return i.value();
} }
const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh, ImageRoundRadius radius, RectParts corners) const { const QPixmap &Image::pixBlurredSingle(
Data::FileOrigin origin,
int w,
int h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners) const {
checkload(); checkload();
if (w <= 0 || !width() || !height()) { if (w <= 0 || !width() || !height()) {
@ -726,7 +766,7 @@ const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh,
if (i != _sizesCache.cend()) { if (i != _sizesCache.cend()) {
globalAcquiredSize -= int64(i->width()) * i->height() * 4; globalAcquiredSize -= int64(i->width()) * i->height() * 4;
} }
auto p = pixNoCache(w, h, options, outerw, outerh); auto p = pixNoCache(origin, w, h, options, outerw, outerh);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor()); if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p); i = _sizesCache.insert(k, p);
if (!p.isNull()) { if (!p.isNull()) {
@ -736,15 +776,22 @@ const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh,
return i.value(); return i.value();
} }
QPixmap Image::pixNoCache(int w, int h, Images::Options options, int outerw, int outerh, const style::color *colored) const { QPixmap Image::pixNoCache(
if (!loading()) const_cast<Image*>(this)->load(); Data::FileOrigin origin,
int w,
int h,
Images::Options options,
int outerw,
int outerh,
const style::color *colored) const {
if (!loading()) const_cast<Image*>(this)->load(origin);
restore(); restore();
if (_data.isNull()) { if (_data.isNull()) {
if (h <= 0 && height() > 0) { if (h <= 0 && height() > 0) {
h = qRound(width() * w / float64(height())); h = qRound(width() * w / float64(height()));
} }
return blank()->pixNoCache(w, h, options, outerw, outerh); return blank()->pixNoCache(origin, w, h, options, outerw, outerh);
} }
if (isNull() && outerw > 0 && outerh > 0) { if (isNull() && outerw > 0 && outerh > 0) {
@ -790,10 +837,15 @@ QPixmap Image::pixNoCache(int w, int h, Images::Options options, int outerw, int
return Images::pixmap(_data.toImage(), w, h, options, outerw, outerh, colored); return Images::pixmap(_data.toImage(), w, h, options, outerw, outerh, colored);
} }
QPixmap Image::pixColoredNoCache(style::color add, int32 w, int32 h, bool smooth) const { QPixmap Image::pixColoredNoCache(
const_cast<Image*>(this)->load(); Data::FileOrigin origin,
style::color add,
int32 w,
int32 h,
bool smooth) const {
const_cast<Image*>(this)->load(origin);
restore(); restore();
if (_data.isNull()) return blank()->pix(); if (_data.isNull()) return blank()->pix(origin);
auto img = _data.toImage(); auto img = _data.toImage();
if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) { if (w <= 0 || !width() || !height() || (w == width() && (h <= 0 || h == height()))) {
@ -805,10 +857,14 @@ QPixmap Image::pixColoredNoCache(style::color add, int32 w, int32 h, bool smooth
return App::pixmapFromImageInPlace(Images::prepareColored(add, img.scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation))); return App::pixmapFromImageInPlace(Images::prepareColored(add, img.scaled(w, h, Qt::IgnoreAspectRatio, smooth ? Qt::SmoothTransformation : Qt::FastTransformation)));
} }
QPixmap Image::pixBlurredColoredNoCache(style::color add, int32 w, int32 h) const { QPixmap Image::pixBlurredColoredNoCache(
const_cast<Image*>(this)->load(); Data::FileOrigin origin,
style::color add,
int32 w,
int32 h) const {
const_cast<Image*>(this)->load(origin);
restore(); restore();
if (_data.isNull()) return blank()->pix(); if (_data.isNull()) return blank()->pix(origin);
auto img = Images::prepareBlur(_data.toImage()); auto img = Images::prepareBlur(_data.toImage());
if (h <= 0) { if (h <= 0) {
@ -933,7 +989,7 @@ void RemoteImage::destroyLoaderDelayed(FileLoader *newValue) const {
void RemoteImage::loadLocal() { void RemoteImage::loadLocal() {
if (loaded() || amLoading()) return; if (loaded() || amLoading()) return;
_loader = createLoader(LoadFromLocalOnly, true); _loader = createLoader(base::none, LoadFromLocalOnly, true);
if (_loader) _loader->start(); if (_loader) _loader->start();
} }
@ -963,7 +1019,9 @@ bool RemoteImage::amLoading() const {
return _loader && _loader != CancelledFileLoader; return _loader && _loader != CancelledFileLoader;
} }
void RemoteImage::automaticLoad(const HistoryItem *item) { void RemoteImage::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (loaded()) return; if (loaded()) return;
if (_loader != CancelledFileLoader && item) { if (_loader != CancelledFileLoader && item) {
@ -977,7 +1035,10 @@ void RemoteImage::automaticLoad(const HistoryItem *item) {
if (_loader) { if (_loader) {
if (loadFromCloud) _loader->permitLoadFromCloud(); if (loadFromCloud) _loader->permitLoadFromCloud();
} else { } else {
_loader = createLoader(loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true); _loader = createLoader(
origin,
loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly,
true);
if (_loader) _loader->start(); if (_loader) _loader->start();
} }
} }
@ -988,20 +1049,28 @@ void RemoteImage::automaticLoadSettingsChanged() {
_loader = 0; _loader = 0;
} }
void RemoteImage::load(bool loadFirst, bool prior) { void RemoteImage::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (loaded()) return; if (loaded()) return;
if (!_loader) { if (!_loader) {
_loader = createLoader(LoadFromCloudOrLocal, false); _loader = createLoader(origin, LoadFromCloudOrLocal, false);
} }
if (amLoading()) { if (amLoading()) {
_loader->start(loadFirst, prior); _loader->start(loadFirst, prior);
} }
} }
void RemoteImage::loadEvenCancelled(bool loadFirst, bool prior) { void RemoteImage::loadEvenCancelled(
if (_loader == CancelledFileLoader) _loader = 0; Data::FileOrigin origin,
return load(loadFirst, prior); bool loadFirst,
bool prior) {
if (_loader == CancelledFileLoader) {
_loader = nullptr;
}
return load(origin, loadFirst, prior);
} }
RemoteImage::~RemoteImage() { RemoteImage::~RemoteImage() {
@ -1070,9 +1139,17 @@ void StorageImage::setInformation(int32 size, int32 width, int32 height) {
_location.setSize(width, height); _location.setSize(width, height);
} }
FileLoader *StorageImage::createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) { FileLoader *StorageImage::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
if (_location.isNull()) return 0; if (_location.isNull()) return 0;
return new mtpFileLoader(&_location, _size, fromCloud, autoLoading); return new mtpFileLoader(
&_location,
origin,
_size,
fromCloud,
autoLoading);
} }
WebFileImage::WebFileImage( WebFileImage::WebFileImage(
@ -1116,10 +1193,16 @@ void WebFileImage::setInformation(int size, int width, int height) {
} }
FileLoader *WebFileImage::createLoader( FileLoader *WebFileImage::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud, LoadFromCloudSetting fromCloud,
bool autoLoading) { bool autoLoading) {
if (_location.isNull()) return 0; return _location.isNull()
return new mtpFileLoader(&_location, _size, fromCloud, autoLoading); ? nullptr
: new mtpFileLoader(
&_location,
_size,
fromCloud,
autoLoading);
} }
DelayedStorageImage::DelayedStorageImage() : StorageImage(StorageImageLocation()) DelayedStorageImage::DelayedStorageImage() : StorageImage(StorageImageLocation())
@ -1143,12 +1226,13 @@ DelayedStorageImage::DelayedStorageImage(QByteArray &bytes)
} }
void DelayedStorageImage::setStorageLocation( void DelayedStorageImage::setStorageLocation(
Data::FileOrigin origin,
const StorageImageLocation location) { const StorageImageLocation location) {
_location = location; _location = location;
if (_loadRequested) { if (_loadRequested) {
if (!_loadCancelled) { if (!_loadCancelled) {
if (_loadFromCloud) { if (_loadFromCloud) {
load(); load(origin);
} else { } else {
loadLocal(); loadLocal();
} }
@ -1157,7 +1241,9 @@ void DelayedStorageImage::setStorageLocation(
} }
} }
void DelayedStorageImage::automaticLoad(const HistoryItem *item) { void DelayedStorageImage::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (_location.isNull()) { if (_location.isNull()) {
if (!_loadCancelled && item) { if (!_loadCancelled && item) {
bool loadFromCloud = false; bool loadFromCloud = false;
@ -1175,7 +1261,7 @@ void DelayedStorageImage::automaticLoad(const HistoryItem *item) {
} }
} }
} else { } else {
StorageImage::automaticLoad(item); StorageImage::automaticLoad(origin, item);
} }
} }
@ -1184,17 +1270,23 @@ void DelayedStorageImage::automaticLoadSettingsChanged() {
StorageImage::automaticLoadSettingsChanged(); StorageImage::automaticLoadSettingsChanged();
} }
void DelayedStorageImage::load(bool loadFirst, bool prior) { void DelayedStorageImage::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_location.isNull()) { if (_location.isNull()) {
_loadRequested = _loadFromCloud = true; _loadRequested = _loadFromCloud = true;
} else { } else {
StorageImage::load(loadFirst, prior); StorageImage::load(origin, loadFirst, prior);
} }
} }
void DelayedStorageImage::loadEvenCancelled(bool loadFirst, bool prior) { void DelayedStorageImage::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
_loadCancelled = false; _loadCancelled = false;
StorageImage::loadEvenCancelled(loadFirst, prior); StorageImage::loadEvenCancelled(origin, loadFirst, prior);
} }
bool DelayedStorageImage::displayLoading() const { bool DelayedStorageImage::displayLoading() const {
@ -1245,7 +1337,10 @@ void WebImage::setInformation(int32 size, int32 width, int32 height) {
setSize(width, height); setSize(width, height);
} }
FileLoader *WebImage::createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) { FileLoader *WebImage::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
return new webFileLoader(_url, QString(), fromCloud, autoLoading); return new webFileLoader(_url, QString(), fromCloud, autoLoading);
} }

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "base/flags.h" #include "base/flags.h"
#include "data/data_file_origin.h"
enum class ImageRoundRadius { enum class ImageRoundRadius {
None, None,
@ -66,7 +67,6 @@ inline QPixmap pixmap(QImage img, int w, int h, Options options, int outerw, int
} // namespace Images } // namespace Images
class FileLoader; class FileLoader;
class mtpFileLoader;
enum LoadFromCloudSetting { enum LoadFromCloudSetting {
LoadFromCloudOrLocal, LoadFromCloudOrLocal,
@ -250,7 +250,9 @@ public:
Image(const QPixmap &pixmap, QByteArray format = QByteArray()); Image(const QPixmap &pixmap, QByteArray format = QByteArray());
Image(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap); Image(const QByteArray &filecontent, QByteArray format, const QPixmap &pixmap);
virtual void automaticLoad(const HistoryItem *item) { // auto load photo virtual void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
} }
virtual void automaticLoadSettingsChanged() { virtual void automaticLoadSettingsChanged() {
} }
@ -273,18 +275,74 @@ public:
return 0; return 0;
} }
const QPixmap &pix(int32 w = 0, int32 h = 0) const; const QPixmap &pix(
const QPixmap &pixRounded(int32 w = 0, int32 h = 0, ImageRoundRadius radius = ImageRoundRadius::None, RectParts corners = RectPart::AllCorners) const; Data::FileOrigin origin,
const QPixmap &pixBlurred(int32 w = 0, int32 h = 0) const; int32 w = 0,
const QPixmap &pixColored(style::color add, int32 w = 0, int32 h = 0) const; int32 h = 0) const;
const QPixmap &pixBlurredColored(style::color add, int32 w = 0, int32 h = 0) const; const QPixmap &pixRounded(
const QPixmap &pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, RectParts corners = RectPart::AllCorners, const style::color *colored = nullptr) const; Data::FileOrigin origin,
const QPixmap &pixBlurredSingle(int32 w, int32 h, int32 outerw, int32 outerh, ImageRoundRadius radius, RectParts corners = RectPart::AllCorners) const; int32 w = 0,
const QPixmap &pixCircled(int32 w = 0, int32 h = 0) const; int32 h = 0,
const QPixmap &pixBlurredCircled(int32 w = 0, int32 h = 0) const; ImageRoundRadius radius = ImageRoundRadius::None,
QPixmap pixNoCache(int w = 0, int h = 0, Images::Options options = 0, int outerw = -1, int outerh = -1, const style::color *colored = nullptr) const; RectParts corners = RectPart::AllCorners) const;
QPixmap pixColoredNoCache(style::color add, int32 w = 0, int32 h = 0, bool smooth = false) const; const QPixmap &pixBlurred(
QPixmap pixBlurredColoredNoCache(style::color add, int32 w, int32 h = 0) const; Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixColored(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixBlurredColored(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners,
const style::color *colored = nullptr) const;
const QPixmap &pixBlurredSingle(
Data::FileOrigin origin,
int32 w,
int32 h,
int32 outerw,
int32 outerh,
ImageRoundRadius radius,
RectParts corners = RectPart::AllCorners) const;
const QPixmap &pixCircled(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
const QPixmap &pixBlurredCircled(
Data::FileOrigin origin,
int32 w = 0,
int32 h = 0) const;
QPixmap pixNoCache(
Data::FileOrigin origin,
int w = 0,
int h = 0,
Images::Options options = 0,
int outerw = -1,
int outerh = -1,
const style::color *colored = nullptr) const;
QPixmap pixColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w = 0,
int32 h = 0,
bool smooth = false) const;
QPixmap pixBlurredColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h = 0) const;
int32 width() const { int32 width() const {
return qMax(countWidth(), 1); return qMax(countWidth(), 1);
@ -294,10 +352,16 @@ public:
return qMax(countHeight(), 1); return qMax(countHeight(), 1);
} }
virtual void load(bool loadFirst = false, bool prior = true) { virtual void load(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) {
} }
virtual void loadEvenCancelled(bool loadFirst = false, bool prior = true) { virtual void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) {
} }
virtual const StorageImageLocation &location() const { virtual const StorageImageLocation &location() const {
@ -381,7 +445,9 @@ inline StorageKey storageKey(const WebFileLocation &location) {
class RemoteImage : public Image { class RemoteImage : public Image {
public: public:
void automaticLoad(const HistoryItem *item) override; // auto load photo void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) override; // auto load photo
void automaticLoadSettingsChanged() override; void automaticLoadSettingsChanged() override;
bool loaded() const override; bool loaded() const override;
@ -393,10 +459,18 @@ public:
float64 progress() const override; float64 progress() const override;
int32 loadOffset() const override; int32 loadOffset() const override;
void setData(QByteArray &bytes, const QByteArray &format = QByteArray()); void setData(
QByteArray &bytes,
const QByteArray &format = QByteArray());
void load(bool loadFirst = false, bool prior = true) override; void load(
void loadEvenCancelled(bool loadFirst = false, bool prior = true) override; Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) override;
void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) override;
~RemoteImage(); ~RemoteImage();
@ -407,7 +481,10 @@ protected:
return QSize(); return QSize();
} }
virtual void setInformation(int32 size, int32 width, int32 height) = 0; virtual void setInformation(int32 size, int32 width, int32 height) = 0;
virtual FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) = 0; virtual FileLoader *createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) = 0;
void checkload() const override { void checkload() const override {
doCheckload(); doCheckload();
@ -434,26 +511,36 @@ public:
protected: protected:
void setInformation(int32 size, int32 width, int32 height) override; void setInformation(int32 size, int32 width, int32 height) override;
FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) override; FileLoader *createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) override;
bool hasLocalCopy() const override; bool hasLocalCopy() const override;
StorageImageLocation _location;
int32 _size;
int32 countWidth() const override; int32 countWidth() const override;
int32 countHeight() const override; int32 countHeight() const override;
StorageImageLocation _location;
int32 _size;
}; };
class WebFileImage : public RemoteImage { class WebFileImage : public RemoteImage {
public: public:
WebFileImage(const WebFileLocation &location, QSize box, int size = 0); WebFileImage(const WebFileLocation &location, QSize box, int size = 0);
WebFileImage(const WebFileLocation &location, int width, int height, int size = 0); WebFileImage(
const WebFileLocation &location,
int width,
int height,
int size = 0);
protected: protected:
void setInformation(int size, int width, int height) override; void setInformation(int size, int width, int height) override;
FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) override; FileLoader *createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) override;
QSize shrinkBox() const override { QSize shrinkBox() const override {
return _box; return _box;
@ -461,25 +548,26 @@ protected:
bool hasLocalCopy() const override; bool hasLocalCopy() const override;
int countWidth() const override;
int countHeight() const override;
WebFileLocation _location; WebFileLocation _location;
QSize _box; QSize _box;
int _width = 0; int _width = 0;
int _height = 0; int _height = 0;
int _size = 0; int _size = 0;
int countWidth() const override;
int countHeight() const override;
}; };
class DelayedStorageImage : public StorageImage { class DelayedStorageImage : public StorageImage {
public: public:
DelayedStorageImage(); DelayedStorageImage();
DelayedStorageImage(int32 w, int32 h); DelayedStorageImage(int32 w, int32 h);
DelayedStorageImage(QByteArray &bytes); DelayedStorageImage(QByteArray &bytes);
void setStorageLocation(const StorageImageLocation location); void setStorageLocation(
Data::FileOrigin origin,
const StorageImageLocation location);
virtual DelayedStorageImage *toDelayedStorageImage() override { virtual DelayedStorageImage *toDelayedStorageImage() override {
return this; return this;
@ -488,7 +576,9 @@ public:
return this; return this;
} }
void automaticLoad(const HistoryItem *item) override; // auto load photo void automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) override; // auto load photo
void automaticLoadSettingsChanged() override; void automaticLoadSettingsChanged() override;
bool loading() const override { bool loading() const override {
@ -497,8 +587,14 @@ public:
bool displayLoading() const override; bool displayLoading() const override;
void cancel() override; void cancel() override;
void load(bool loadFirst = false, bool prior = true) override; void load(
void loadEvenCancelled(bool loadFirst = false, bool prior = true) override; Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) override;
void loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst = false,
bool prior = true) override;
private: private:
bool _loadRequested, _loadCancelled, _loadFromCloud; bool _loadRequested, _loadCancelled, _loadFromCloud;
@ -518,7 +614,10 @@ protected:
return _box; return _box;
} }
void setInformation(int32 size, int32 width, int32 height) override; void setInformation(int32 size, int32 width, int32 height) override;
FileLoader *createLoader(LoadFromCloudSetting fromCloud, bool autoLoading) override; FileLoader *createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) override;
int32 countWidth() const override; int32 countWidth() const override;
int32 countHeight() const override; int32 countHeight() const override;

View file

@ -850,7 +850,9 @@ void MediaPreviewWidget::resizeEvent(QResizeEvent *e) {
update(); update();
} }
void MediaPreviewWidget::showPreview(DocumentData *document) { void MediaPreviewWidget::showPreview(
Data::FileOrigin origin,
not_null<DocumentData*> document) {
if (!document if (!document
|| (!document->isAnimation() && !document->sticker()) || (!document->isAnimation() && !document->sticker())
|| document->isVideoMessage()) { || document->isVideoMessage()) {
@ -859,19 +861,23 @@ void MediaPreviewWidget::showPreview(DocumentData *document) {
} }
startShow(); startShow();
_origin = origin;
_photo = nullptr; _photo = nullptr;
_document = document; _document = document;
fillEmojiString(); fillEmojiString();
resetGifAndCache(); resetGifAndCache();
} }
void MediaPreviewWidget::showPreview(PhotoData *photo) { void MediaPreviewWidget::showPreview(
if (!photo || photo->full->isNull()) { Data::FileOrigin origin,
not_null<PhotoData*> photo) {
if (photo->full->isNull()) {
hidePreview(); hidePreview();
return; return;
} }
startShow(); startShow();
_origin = origin;
_photo = photo; _photo = photo;
_document = nullptr; _document = nullptr;
fillEmojiString(); fillEmojiString();
@ -974,17 +980,17 @@ QPixmap MediaPreviewWidget::currentImage() const {
if (_document->sticker()->img->isNull()) { if (_document->sticker()->img->isNull()) {
if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) { if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _document->thumb->pixBlurred(s.width(), s.height()); _cache = _document->thumb->pixBlurred(_origin, s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} }
} else { } else {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _document->sticker()->img->pix(s.width(), s.height()); _cache = _document->sticker()->img->pix(_origin, s.width(), s.height());
_cacheStatus = CacheLoaded; _cacheStatus = CacheLoaded;
} }
} }
} else { } else {
_document->automaticLoad(nullptr); _document->automaticLoad(_origin, nullptr);
if (_document->loaded()) { if (_document->loaded()) {
if (!_gif && !_gif.isBad()) { if (!_gif && !_gif.isBad()) {
auto that = const_cast<MediaPreviewWidget*>(this); auto that = const_cast<MediaPreviewWidget*>(this);
@ -1001,7 +1007,7 @@ QPixmap MediaPreviewWidget::currentImage() const {
} }
if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) { if (_cacheStatus != CacheThumbLoaded && _document->thumb->loaded()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _document->thumb->pixBlurred(s.width(), s.height()); _cache = _document->thumb->pixBlurred(_origin, s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} }
} }
@ -1009,16 +1015,16 @@ QPixmap MediaPreviewWidget::currentImage() const {
if (_cacheStatus != CacheLoaded) { if (_cacheStatus != CacheLoaded) {
if (_photo->full->loaded()) { if (_photo->full->loaded()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _photo->full->pix(s.width(), s.height()); _cache = _photo->full->pix(_origin, s.width(), s.height());
_cacheStatus = CacheLoaded; _cacheStatus = CacheLoaded;
} else { } else {
if (_cacheStatus != CacheThumbLoaded && _photo->thumb->loaded()) { if (_cacheStatus != CacheThumbLoaded && _photo->thumb->loaded()) {
QSize s = currentDimensions(); QSize s = currentDimensions();
_cache = _photo->thumb->pixBlurred(s.width(), s.height()); _cache = _photo->thumb->pixBlurred(_origin, s.width(), s.height());
_cacheStatus = CacheThumbLoaded; _cacheStatus = CacheThumbLoaded;
} }
_photo->thumb->load(); _photo->thumb->load(_origin);
_photo->full->load(); _photo->full->load(_origin);
} }
} }

View file

@ -201,8 +201,12 @@ class MediaPreviewWidget : public TWidget, private base::Subscriber {
public: public:
MediaPreviewWidget(QWidget *parent, not_null<Window::Controller*> controller); MediaPreviewWidget(QWidget *parent, not_null<Window::Controller*> controller);
void showPreview(DocumentData *document); void showPreview(
void showPreview(PhotoData *photo); Data::FileOrigin origin,
not_null<DocumentData*> document);
void showPreview(
Data::FileOrigin origin,
not_null<PhotoData*> photo);
void hidePreview(); void hidePreview();
~MediaPreviewWidget(); ~MediaPreviewWidget();
@ -222,6 +226,7 @@ private:
Animation _a_shown; Animation _a_shown;
bool _hiding = false; bool _hiding = false;
Data::FileOrigin _origin;
DocumentData *_document = nullptr; DocumentData *_document = nullptr;
PhotoData *_photo = nullptr; PhotoData *_photo = nullptr;
Media::Clip::ReaderPointer _gif; Media::Clip::ReaderPointer _gif;

View file

@ -179,6 +179,7 @@
<(src_loc)/data/data_feed.h <(src_loc)/data/data_feed.h
<(src_loc)/data/data_feed_messages.cpp <(src_loc)/data/data_feed_messages.cpp
<(src_loc)/data/data_feed_messages.h <(src_loc)/data/data_feed_messages.h
<(src_loc)/data/data_file_origin.h
<(src_loc)/data/data_flags.h <(src_loc)/data/data_flags.h
<(src_loc)/data/data_game.h <(src_loc)/data/data_game.h
<(src_loc)/data/data_groups.cpp <(src_loc)/data/data_groups.cpp