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;
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;
inputTakeoutFileLocation#29be5899 = InputFileLocation;
@ -508,7 +508,7 @@ inputDocumentEmpty#72f0eaae = InputDocument;
inputDocument#1abfb575 id:long access_hash:long file_reference:bytes = InputDocument;
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;
@ -1331,4 +1331,4 @@ langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector<strin
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
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) {
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;
if (index >= _bgCount) break;
const App::WallPaper &paper(App::cServerBackgrounds().at(index));
paper.thumb->load();
const auto &paper = App::cServerBackgrounds()[index];
paper.thumb->load(Data::FileOrigin());
int x = st::backgroundPadding + j * (st::backgroundSize.width() + 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);
if (paper.id == Window::Theme::Background()->id()) {

View file

@ -648,7 +648,13 @@ void DeleteMessagesBox::deleteAndClear() {
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)
, _status(this, st::confirmInviteStatus)
, _participants(participants) {
@ -675,7 +681,7 @@ ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, bool isChanne
_photo = ImagePtr(location);
if (!_photo->loaded()) {
subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
_photo->load();
_photo->load(Data::FileOrigin());
}
}
}
@ -730,15 +736,31 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
Painter p(this);
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 {
_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 left = (width() - sumWidth) / 2;
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;
}
}

View file

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

View file

@ -281,7 +281,9 @@ void StickerSetBox::Inner::mouseMoveEvent(QMouseEvent *e) {
int index = stickerFromGlobalPos(e->globalPos());
if (index >= 0 && index < _pack.size() && index != _previewShown) {
_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());
if (index >= 0 && index < _pack.size()) {
_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);
}
const auto goodThumb = doc->hasGoodStickerThumb();
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());
}
}
doc->checkStickerThumb();
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;
@ -401,10 +393,11 @@ void StickerSetBox::Inner::paintEvent(QPaintEvent *e) {
if (w < 1) w = 1;
if (h < 1) h = 1;
QPoint ppos = pos + QPoint((st::stickersSize.width() - w) / 2, (st::stickersSize.height() - h) / 2);
if (goodThumb) {
p.drawPixmapLeft(ppos, width(), doc->thumb->pix(w, h));
} else if (!doc->sticker()->img->isNull()) {
p.drawPixmapLeft(ppos, width(), doc->sticker()->img->pix(w, h));
if (const auto image = doc->getStickerThumb()) {
p.drawPixmapLeft(
ppos,
width(),
image->pix(doc->stickerSetOrigin(), w, h));
}
}
}

View file

@ -568,7 +568,22 @@ void StickersBox::setInnerFocus() {
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)
, count(count)
, title(title)
@ -782,8 +797,11 @@ void StickersBox::Inner::paintRow(Painter &p, Row *set, int index, TimeMs ms) {
}
if (set->sticker) {
set->sticker->thumb->load();
auto pix = set->sticker->thumb->pix(set->pixw, set->pixh);
const auto origin = Data::FileOriginStickerSet(
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);
}
@ -1342,7 +1360,20 @@ void StickersBox::Inner::rebuildMegagroupSet() {
_megagroupSetField->setText(it->shortName);
_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;
if (!_megagroupSelectedRemove) {
@ -1512,7 +1543,20 @@ void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameW
QString title = fillSetTitle(set, maxNameWidth, &titleWidth);
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);
}

View file

@ -190,13 +190,27 @@ public slots:
private:
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 {
return (id == Stickers::CloudRecentSetId);
}
~Row();
uint64 id = 0;
uint64 accessHash = 0;
DocumentData *sticker = nullptr;
int32 count = 0;
QString title;

View file

@ -503,7 +503,7 @@ void Panel::processUserPhoto() {
? Auth().data().photo(_user->userpicPhotoId()).get()
: nullptr;
if (isGoodUserPhoto(photo)) {
photo->full->load(true);
photo->full->load(_user->userpicPhotoOrigin(), true);
} else if (_user->userpicPhotoUnknown() || (photo && !photo->date)) {
Auth().api().requestFullPeer(_user);
}
@ -540,7 +540,13 @@ void Panel::createUserpicCache(ImagePtr image) {
height = qMax((height * size) / width, 1);
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());
} else {
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;
if (index >= _srows->size()) break;
DocumentData *sticker = _srows->at(index);
if (!sticker->sticker()) continue;
const auto document = _srows->at(index);
if (!document->sticker()) continue;
QPoint pos(st::stickerPanPadding + col * st::stickerPanSize.width(), st::stickerPanPadding + row * st::stickerPanSize.height());
if (_sel == index) {
@ -561,23 +561,16 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
App::roundRect(p, QRect(tl, st::stickerPanSize), st::emojiPanHover, StickerHoverCorners);
}
const auto goodThumb = sticker->hasGoodStickerThumb();
if (goodThumb) {
sticker->thumb->load();
} else {
sticker->checkSticker();
}
document->checkStickerThumb();
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;
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 (h < 1) h = 1;
QPoint ppos = pos + QPoint((st::stickerPanSize.width() - w) / 2, (st::stickerPanSize.height() - h) / 2);
if (goodThumb) {
p.drawPixmapLeft(ppos, width(), sticker->thumb->pix(w, h));
} else if (!sticker->sticker()->img->isNull()) {
p.drawPixmapLeft(ppos, width(), sticker->sticker()->img->pix(w, h));
if (const auto image = document->getStickerThumb()) {
p.drawPixmapLeft(ppos, width(), image->pix(document->stickerSetOrigin(), w, h));
}
}
}
@ -901,7 +894,9 @@ void FieldAutocompleteInner::onUpdateSelected(bool force) {
if (_down >= 0 && _sel >= 0 && _down != _sel) {
_down = _sel;
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() {
if (_down >= 0 && _down < _srows->size()) {
Ui::showMediaPreview(_srows->at(_down));
Ui::showMediaPreview(
(*_srows)[_down]->stickerSetOrigin(),
(*_srows)[_down]);
_previewShown = true;
}
}

View file

@ -343,16 +343,21 @@ void GifsListWidget::selectInlineResult(int row, int column) {
if (photo->medium->loaded() || photo->thumb->loaded()) {
emit selected(photo);
} else if (!photo->medium->loading()) {
photo->thumb->loadEvenCancelled();
photo->medium->loadEvenCancelled();
photo->thumb->loadEvenCancelled(Data::FileOrigin());
photo->medium->loadEvenCancelled(Data::FileOrigin());
}
} else if (auto document = item->getDocument()) {
} else if (const auto document = item->getDocument()) {
if (document->loaded()) {
emit selected(document);
} else if (document->loading()) {
document->cancel();
} else {
DocumentOpenClickHandler::doOpen(document, nullptr, ActionOnLoadNone);
DocumentOpenClickHandler::Open(
document->stickerOrGifOrigin(),
document,
nullptr,
ActionOnLoadNone);
}
} else if (auto inlineResult = item->getResult()) {
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());
}
Data::FileOrigin GifsListWidget::inlineItemFileOrigin() {
return _inlineQuery.isEmpty()
? Data::FileOriginSavedGifs()
: Data::FileOrigin();
}
void GifsListWidget::afterShown() {
if (_footer) {
_footer->stealFocus();
@ -948,10 +959,14 @@ void GifsListWidget::updateSelected() {
_pressed = _selected;
if (row >= 0 && col >= 0) {
auto layout = _rows[row].items[col];
if (auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(previewDocument);
} else if (auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(previewPhoto);
if (const auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(
Data::FileOriginSavedGifs(),
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;
if (row < _rows.size() && col < _rows[row].items.size()) {
auto layout = _rows[row].items[col];
if (auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(previewDocument);
if (const auto previewDocument = layout->getPreviewDocument()) {
Ui::showMediaPreview(
Data::FileOriginSavedGifs(),
previewDocument);
_previewShown = true;
} else if (auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(previewPhoto);
} else if (const auto previewPhoto = layout->getPreviewPhoto()) {
Ui::showMediaPreview(
Data::FileOrigin(),
previewPhoto);
_previewShown = true;
}
}

View file

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

View file

@ -258,7 +258,7 @@ void StickersListWidget::Footer::enumerateVisibleIcons(Callback callback) {
void StickersListWidget::Footer::preloadImages() {
enumerateVisibleIcons([](const StickerIcon &icon, int x) {
if (auto sticker = icon.sticker) {
sticker->thumb->load();
sticker->thumb->load(sticker->stickerSetOrigin());
}
});
}
@ -628,8 +628,9 @@ void StickersListWidget::Footer::paintSetIcon(
const StickerIcon &icon,
int x) const {
if (icon.sticker) {
icon.sticker->thumb->load();
auto pix = icon.sticker->thumb->pix(icon.pixw, icon.pixh);
const auto origin = icon.sticker->stickerSetOrigin();
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);
} 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) {
auto sticker = set.pack[index];
if (!sticker->sticker()) return;
auto document = set.pack[index];
if (!document->sticker()) return;
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);
}
const auto goodThumb = sticker->hasGoodStickerThumb();
if (goodThumb) {
sticker->thumb->load();
} else {
sticker->checkSticker();
}
document->checkStickerThumb();
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;
auto w = qMax(qRound(coef * sticker->dimensions.width()), 1);
auto h = qMax(qRound(coef * sticker->dimensions.height()), 1);
auto w = qMax(qRound(coef * document->dimensions.width()), 1);
auto h = qMax(qRound(coef * document->dimensions.height()), 1);
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()) {
p.drawPixmapLeft(
ppos,
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)) {
@ -1764,15 +1761,10 @@ void StickersListWidget::preloadImages() {
for (int j = 0; j != count; ++j) {
if (++k > _columnCount * (_columnCount + 1)) break;
auto sticker = sets[i].pack.at(j);
if (!sticker || !sticker->sticker()) continue;
const auto document = sets[i].pack[j];
if (!document || !document->sticker()) continue;
const auto goodThumb = sticker->hasGoodStickerThumb();
if (goodThumb) {
sticker->thumb->load();
} else {
sticker->automaticLoad(0);
}
document->checkStickerThumb();
}
if (k > _columnCount * (_columnCount + 1)) break;
}
@ -2162,7 +2154,9 @@ void StickersListWidget::setSelected(OverState newSelected) {
Assert(sticker->section >= 0 && sticker->section < sets.size());
auto &set = sets[sticker->section];
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());
auto &set = sets[sticker->section];
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;
}
}

View file

@ -1467,7 +1467,6 @@ auto MtpChecker::parseFile(const MTPmessages_Messages &result) const
const auto location = MTP_inputDocumentFileLocation(
fields.vid,
fields.vaccess_hash,
fields.vversion,
fields.vfile_reference);
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);
}
void DocumentOpenClickHandler::doOpen(
void DocumentOpenClickHandler::Open(
Data::FileOrigin origin,
not_null<DocumentData*> data,
HistoryItem *context,
ActionOnLoad action) {
@ -334,7 +335,7 @@ void DocumentOpenClickHandler::doOpen(
if (filename.isEmpty()) return;
}
data->save(filename, action, msgId);
data->save(origin, filename, action, msgId);
}
void DocumentOpenClickHandler::onClickImpl() const {
@ -342,14 +343,15 @@ void DocumentOpenClickHandler::onClickImpl() const {
const auto action = data->isVoiceMessage()
? ActionOnLoadNone
: ActionOnLoadOpen;
doOpen(data, getActionItem(), action);
Open(context(), data, getActionItem(), action);
}
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,
bool forceSavingAs) {
if (!data->date) return;
@ -365,13 +367,13 @@ void DocumentSaveClickHandler::doSave(
auto filename = filepath.isEmpty() ? QString() : fileinfo.fileName();
auto newfname = documentSaveFilename(data, forceSavingAs, filename, filedir);
if (!newfname.isEmpty()) {
data->save(newfname, ActionOnLoadNone, FullMsgId());
data->save(origin, newfname, ActionOnLoadNone, FullMsgId());
}
}
}
void DocumentSaveClickHandler::onClickImpl() const {
doSave(document());
Save(context(), document());
}
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() {
if (!waveform.isEmpty()
&& waveform[0] == -1
@ -514,12 +525,14 @@ void DocumentData::forget() {
_data.clear();
}
void DocumentData::automaticLoad(const HistoryItem *item) {
void DocumentData::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (loaded() || status != FileReady) return;
if (saveToCache() && _loader != CancelledMtpFileLoader) {
if (type == StickerDocument) {
save(QString(), _actionOnLoad, _actionOnLoadMsgId);
save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId);
} else if (isAnimation()) {
bool loadFromCloud = false;
if (item) {
@ -531,7 +544,7 @@ void DocumentData::automaticLoad(const HistoryItem *item) {
} else { // if load at least anywhere
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()) {
if (item) {
bool loadFromCloud = false;
@ -540,7 +553,7 @@ void DocumentData::automaticLoad(const HistoryItem *item) {
} else {
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(
Data::FileOrigin origin,
const QString &toFile,
ActionOnLoad action,
const FullMsgId &actionMsgId,
@ -768,8 +782,8 @@ void DocumentData::save(
_dc,
id,
_access,
_version,
_fileReference,
origin,
locationType(),
toFile,
size,
@ -924,7 +938,7 @@ bool DocumentData::isStickerSetInstalled() const {
return false;
}
ImagePtr DocumentData::makeReplyPreview() {
ImagePtr DocumentData::makeReplyPreview(Data::FileOrigin origin) {
if (replyPreview->isNull() && !thumb->isNull()) {
if (thumb->loaded()) {
int w = thumb->width(), h = thumb->height();
@ -934,10 +948,10 @@ ImagePtr DocumentData::makeReplyPreview() {
thumbSize *= cIntRetinaFactor();
auto options = Images::Option::Smooth | (isVideoMessage() ? Images::Option::Circled : Images::Option::None) | Images::Option::TransparentBackground;
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");
} else {
thumb->load();
thumb->load(origin);
}
}
return replyPreview;
@ -953,10 +967,10 @@ void DocumentData::checkSticker() {
const auto data = sticker();
if (!data) return;
automaticLoad(nullptr);
automaticLoad(stickerSetOrigin(), nullptr);
if (data->img->isNull() && loaded()) {
if (_data.isEmpty()) {
const FileLocation &loc(location(true));
const auto &loc = location(true);
if (loc.accessEnable()) {
data->img = ImagePtr(loc.name());
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() {
return isSong()
? static_cast<SongData*>(_additional.get())
@ -1026,7 +1072,7 @@ void DocumentData::setMimeString(const QString &mime) {
}
MediaKey DocumentData::mediaKey() const {
return ::mediaKey(locationType(), _dc, id, _version);
return ::mediaKey(locationType(), _dc, id);
}
QString DocumentData::composeNameString() const {
@ -1120,20 +1166,6 @@ bool DocumentData::hasGoodStickerThumb() const {
&& ((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(
int32 dc,
uint64 access,

View file

@ -10,23 +10,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_types.h"
class AuthSession;
class mtpFileLoader;
inline uint64 mediaMix32To64(int32 a, int32 b) {
return (uint64(*reinterpret_cast<uint32*>(&a)) << 32)
| uint64(*reinterpret_cast<uint32*>(&b));
}
// Old method, should not be used anymore.
//inline MediaKey mediaKey(LocationType type, int32 dc, const uint64 &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);
// version field removed from document.
inline MediaKey mediaKey(LocationType type, int32 dc, const uint64 &id) {
return MediaKey(mediaMix32To64(type, dc), id);
}
inline StorageKey mediaKey(const MTPDfileLocation &location) {
@ -42,11 +35,12 @@ struct DocumentAdditionalData {
};
struct StickerData : public DocumentAdditionalData {
Data::FileOrigin setOrigin() const;
ImagePtr img;
QString alt;
MTPInputStickerSet set = MTP_inputStickerSetEmpty();
StorageImageLocation loc; // doc thumb location
};
struct SongData : public DocumentAdditionalData {
@ -78,7 +72,9 @@ public:
void setattributes(
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();
enum FilePathResolveType {
@ -93,6 +89,7 @@ public:
QString loadingFilePath() const;
bool displayLoading() const;
void save(
Data::FileOrigin origin,
const QString &toFile,
ActionOnLoad action = ActionOnLoadNone,
const FullMsgId &actionMsgId = FullMsgId(),
@ -119,10 +116,14 @@ public:
void performActionOnLoad();
void forget();
ImagePtr makeReplyPreview();
ImagePtr makeReplyPreview(Data::FileOrigin origin);
StickerData *sticker() const;
void checkSticker();
void checkStickerThumb();
ImagePtr getStickerThumb();
Data::FileOrigin stickerSetOrigin() const;
Data::FileOrigin stickerOrGifOrigin() const;
bool isStickerSetInstalled() const;
SongData *song();
const SongData *song() const;
@ -147,7 +148,6 @@ public:
bool hasGoodStickerThumb() const;
bool setRemoteVersion(int32 version); // Returns true if version has changed.
void setRemoteLocation(
int32 dc,
uint64 access,
@ -198,11 +198,10 @@ private:
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;
uint64 _access = 0;
QByteArray _fileReference;
int32 _version = 0;
QString _url;
QString _filename;
QString _mimeString;
@ -244,7 +243,8 @@ private:
class DocumentSaveClickHandler : public DocumentClickHandler {
public:
using DocumentClickHandler::DocumentClickHandler;
static void doSave(
static void Save(
Data::FileOrigin origin,
not_null<DocumentData*> document,
bool forceSavingAs = false);
@ -256,7 +256,8 @@ protected:
class DocumentOpenClickHandler : public DocumentClickHandler {
public:
using DocumentClickHandler::DocumentClickHandler;
static void doOpen(
static void Open(
Data::FileOrigin origin,
not_null<DocumentData*> document,
HistoryItem *context,
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 {
return _photo->makeReplyPreview();
return _photo->makeReplyPreview(parent()->fullId());
}
QString MediaPhoto::notificationText() const {
@ -470,7 +470,7 @@ bool MediaFile::hasReplyPreview() const {
}
ImagePtr MediaFile::replyPreview() const {
return _document->makeReplyPreview();
return _document->makeReplyPreview(parent()->fullId());
}
QString MediaFile::chatsListText() const {
@ -935,9 +935,9 @@ bool MediaWebPage::hasReplyPreview() const {
ImagePtr MediaWebPage::replyPreview() const {
if (const auto document = _page->document) {
return document->makeReplyPreview();
return document->makeReplyPreview(parent()->fullId());
} else if (const auto photo = _page->photo) {
return photo->makeReplyPreview();
return photo->makeReplyPreview(parent()->fullId());
}
return ImagePtr();
}
@ -998,9 +998,9 @@ bool MediaGame::hasReplyPreview() const {
ImagePtr MediaGame::replyPreview() const {
if (const auto document = _game->document) {
return document->makeReplyPreview();
return document->makeReplyPreview(parent()->fullId());
} else if (const auto photo = _game->photo) {
return photo->makeReplyPreview();
return photo->makeReplyPreview(parent()->fullId());
}
return ImagePtr();
}
@ -1098,7 +1098,7 @@ bool MediaInvoice::hasReplyPreview() const {
ImagePtr MediaInvoice::replyPreview() const {
if (const auto photo = _invoice.photo) {
return photo->makeReplyPreview();
return photo->makeReplyPreview(parent()->fullId());
}
return ImagePtr();
}

View file

@ -187,7 +187,7 @@ void PeerData::setUserpicPhoto(const MTPPhoto &data) {
ImagePtr PeerData::currentUserpic() const {
if (_userpic) {
_userpic->load();
_userpic->load(userpicPhotoOrigin());
if (_userpic->loaded()) {
if (!useEmptyUserpic()) {
_userpicEmpty = nullptr;
@ -200,7 +200,7 @@ ImagePtr PeerData::currentUserpic() const {
void PeerData::paintUserpic(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) {
p.drawPixmap(x, y, userpic->pixCircled(size, size));
p.drawPixmap(x, y, userpic->pixCircled(userpicPhotoOrigin(), size, size));
} else {
_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 {
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 {
_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 {
if (auto userpic = currentUserpic()) {
p.drawPixmap(x, y, userpic->pix(size, size));
p.drawPixmap(x, y, userpic->pix(userpicPhotoOrigin(), size, size));
} else {
_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 {
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);
result.setDevicePixelRatio(cRetinaFactor());
@ -253,7 +253,7 @@ QPixmap PeerData::genUserpic(int size) const {
QPixmap PeerData::genUserpicRounded(int size) const {
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);
result.setDevicePixelRatio(cRetinaFactor());

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -203,15 +203,17 @@ void showBox(
} // namespace internal
void showMediaPreview(DocumentData *document) {
void showMediaPreview(
Data::FileOrigin origin,
not_null<DocumentData*> document) {
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()) {
w->ui_showMediaPreview(photo);
w->ui_showMediaPreview(origin, photo);
}
}

View file

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

View file

@ -1081,7 +1081,9 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
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();
FileDialog::GetWritePath(
@ -1091,19 +1093,19 @@ void InnerWidget::savePhotoToFile(PhotoData *photo) {
filedialogDefaultName(qsl("photo"), qsl(".jpg")),
crl::guard(this, [=](const QString &result) {
if (!result.isEmpty()) {
photo->full->pix().toImage().save(result, "JPG");
photo->full->pix(Data::FileOrigin()).toImage().save(result, "JPG");
}
}));
}
void InnerWidget::saveDocumentToFile(DocumentData *document) {
DocumentSaveClickHandler::doSave(document, true);
DocumentSaveClickHandler::Save(Data::FileOrigin(), document, true);
}
void InnerWidget::copyContextImage(PhotoData *photo) {
if (!photo || !photo->date || !photo->loaded()) return;
QApplication::clipboard()->setPixmap(photo->full->pix());
QApplication::clipboard()->setPixmap(photo->full->pix(Data::FileOrigin()));
}
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, [=] {
saveDocumentToFile(document);
saveDocumentToFile(itemId, document);
}));
}
}
@ -1639,8 +1639,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
toggleFavedSticker(document);
});
}
_menu->addAction(lang(lng_context_save_image), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [this, document] {
saveDocumentToFile(document);
_menu->addAction(lang(lng_context_save_image), App::LambdaDelayed(st::defaultDropdownMenu.menu.ripple.hideDuration, this, [=] {
saveDocumentToFile(itemId, document);
}));
}
}
@ -1753,7 +1753,7 @@ void HistoryInner::savePhotoToFile(not_null<PhotoData*> photo) {
qsl(".jpg")),
crl::guard(this, [=](const QString &result) {
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) {
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) {
@ -1791,8 +1791,10 @@ void HistoryInner::showContextInFolder(not_null<DocumentData*> document) {
}
}
void HistoryInner::saveDocumentToFile(not_null<DocumentData*> document) {
DocumentSaveClickHandler::doSave(document, true);
void HistoryInner::saveDocumentToFile(
FullMsgId contextId,
not_null<DocumentData*> document) {
DocumentSaveClickHandler::Save(contextId, document, true);
}
void HistoryInner::openContextGif(FullMsgId itemId) {

View file

@ -209,7 +209,9 @@ private:
void copyContextText(FullMsgId itemId);
void showContextInFolder(not_null<DocumentData*> document);
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 showStickerPackInfo(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 previewWidth = replyPreview->width() / 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);
}
}

View file

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

View file

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

View file

@ -258,7 +258,7 @@ HistoryPhoto::HistoryPhoto(
not_null<Element*> parent,
not_null<HistoryItem*> realParent,
not_null<PhotoData*> photo)
: HistoryFileMedia(parent)
: HistoryFileMedia(parent, realParent)
, _data(photo)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
const auto fullId = realParent->fullId();
@ -275,7 +275,7 @@ HistoryPhoto::HistoryPhoto(
not_null<PeerData*> chat,
not_null<PhotoData*> photo,
int width)
: HistoryFileMedia(parent)
: HistoryFileMedia(parent, parent->data())
, _data(photo)
, _serviceWidth(width) {
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<PhotoSaveClickHandler>(_data, contextId, chat),
std::make_shared<PhotoCancelClickHandler>(_data, contextId, chat));
_data->thumb->load();
_data->thumb->load(contextId);
}
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 {
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 loaded = _data->loaded();
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());
if (_serviceWidth > 0) {
const auto pix = loaded
? _data->full->pixCircled(_pixw, _pixh)
: _data->thumb->pixBlurredCircled(_pixw, _pixh);
? _data->full->pixCircled(_realParent->fullId(), _pixw, _pixh)
: _data->thumb->pixBlurredCircled(_realParent->fullId(), _pixw, _pixh);
p.drawPixmap(rthumb.topLeft(), pix);
} else {
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)
| ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None));
const auto pix = loaded
? _data->full->pixSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners)
: _data->thumb->pixBlurredSingle(_pixw, _pixh, paintw, painth, roundRadius, roundCorners);
? _data->full->pixSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners)
: _data->thumb->pixBlurredSingle(_realParent->fullId(), _pixw, _pixh, paintw, painth, roundRadius, roundCorners);
p.drawPixmap(rthumb.topLeft(), pix);
if (selected) {
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
@ -559,7 +559,7 @@ void HistoryPhoto::drawGrouped(
RectParts corners,
not_null<uint64*> cacheKey,
not_null<QPixmap*> cache) const {
_data->automaticLoad(_parent->data());
_data->automaticLoad(_realParent->fullId(), _parent->data());
validateGroupedCache(geometry, corners, cacheKey, cache);
@ -715,7 +715,7 @@ void HistoryPhoto::validateGroupedCache(
const auto &image = loaded ? _data->full : _data->thumb;
*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 {
@ -747,7 +747,7 @@ HistoryVideo::HistoryVideo(
not_null<Element*> parent,
not_null<HistoryItem*> realParent,
not_null<DocumentData*> document)
: HistoryFileMedia(parent)
: HistoryFileMedia(parent, realParent)
, _data(document)
, _thumbw(1)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
@ -757,7 +757,7 @@ HistoryVideo::HistoryVideo(
setStatusSize(FileStatusSizeReady);
_data->thumb->load();
_data->thumb->load(realParent->fullId());
}
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 {
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 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)
| ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None));
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) {
App::complexOverlayRect(p, rthumb, roundRadius, roundCorners);
}
@ -1010,7 +1010,7 @@ void HistoryVideo::drawGrouped(
RectParts corners,
not_null<uint64*> cacheKey,
not_null<QPixmap*> cache) const {
_data->automaticLoad(_parent->data());
_data->automaticLoad(_realParent->fullId(), _parent->data());
validateGroupedCache(geometry, corners, cacheKey, cache);
@ -1155,7 +1155,7 @@ void HistoryVideo::validateGroupedCache(
const auto &image = _data->thumb;
*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 {
@ -1208,7 +1208,7 @@ void HistoryVideo::updateStatusText() const {
HistoryDocument::HistoryDocument(
not_null<Element*> parent,
not_null<DocumentData*> document)
: HistoryFileMedia(parent)
: HistoryFileMedia(parent, parent->data())
, _data(document) {
const auto item = parent->data();
auto caption = createCaption(item);
@ -1293,7 +1293,7 @@ QSize HistoryDocument::countOptimalSize() {
}
auto thumbed = Get<HistoryDocumentThumbed>();
if (thumbed) {
_data->thumb->load();
_data->thumb->load(_realParent->fullId());
auto tw = convertScale(_data->thumb->width());
auto th = convertScale(_data->thumb->height());
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 {
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 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()));
QPixmap thumb;
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 {
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);
if (selected) {
@ -1929,7 +1929,7 @@ TextWithEntities HistoryDocument::getCaption() const {
HistoryGif::HistoryGif(
not_null<Element*> parent,
not_null<DocumentData*> document)
: HistoryFileMedia(parent)
: HistoryFileMedia(parent, parent->data())
, _data(document)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
const auto item = parent->data();
@ -1938,7 +1938,7 @@ HistoryGif::HistoryGif(
setStatusSize(FileStatusSizeReady);
_caption = createCaption(item);
_data->thumb->load();
_data->thumb->load(item->fullId());
}
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;
const auto item = _parent->data();
_data->automaticLoad(item);
_data->automaticLoad(_realParent->fullId(), item);
auto loaded = _data->loaded();
auto displayLoading = (item->id < 0) || _data->displayLoading();
auto selected = (selection == FullSelection);
@ -2220,7 +2220,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, TimeM
}
}
} 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) {
@ -2793,7 +2793,7 @@ HistorySticker::HistorySticker(
: HistoryMedia(parent)
, _data(document)
, _emoji(_data->sticker()->alt) {
_data->thumb->load();
_data->thumb->load(parent->data()->fullId());
if (auto emoji = Ui::Emoji::Find(_emoji)) {
_emoji = emoji->text();
}
@ -2881,15 +2881,15 @@ void HistorySticker::draw(Painter &p, const QRect &r, TextSelection selection, T
if (selected) {
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 {
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 {
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 {
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();
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();
QPixmap pix;
auto pw = qMax(_pixw, lineHeight);
@ -3629,9 +3630,9 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, T
pixw = qRound(pixw * coef);
}
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 {
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);
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);
}
_data->load();
const auto contextId = _parent->data()->fullId();
_data->load(contextId);
auto roundRadius = ImageRoundRadius::Large;
auto roundCorners = ((isBubbleTop() && _title.isEmpty() && _description.isEmpty()) ? (RectPart::TopLeft | RectPart::TopRight) : 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();
QPixmap pix;
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) {
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 {
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);
} else {

View file

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

View file

@ -6616,7 +6616,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
auto replyPreview = drawMsgText->media()->replyPreview();
if (!replyPreview->isNull()) {
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();
}
@ -6651,10 +6651,10 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
if (!preview->isNull()) {
auto to = QRect(forwardLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.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 {
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();
}
@ -6670,14 +6670,14 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
auto previewLeft = st::historyReplySkip + st::webPageLeft;
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())) {
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()) {
auto to = QRect(previewLeft, backy + st::msgReplyPadding.top(), st::msgReplyBarSize.height(), st::msgReplyBarSize.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 {
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();
@ -6782,7 +6782,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
ImagePtr replyPreview = _pinnedBar->msg->media()->replyPreview();
if (!replyPreview->isNull()) {
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();
}

View file

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

View file

@ -1220,10 +1220,11 @@ void ListWidget::showContextMenu(
auto link = ClickHandler::getActive();
const auto itemFullId = item->fullId();
_contextMenu = base::make_unique_q<Ui::PopupMenu>(this);
_contextMenu->addAction(
lang(lng_context_to_msg),
[itemFullId = item->fullId()] {
[itemFullId] {
if (auto item = App::histItemById(itemFullId)) {
Ui::showPeerHistoryAtItem(item);
}
@ -1271,8 +1272,11 @@ void ListWidget::showContextMenu(
auto handler = App::LambdaDelayed(
st::defaultDropdownMenu.menu.ripple.hideDuration,
this,
[document] {
DocumentSaveClickHandler::doSave(document, true);
[=] {
DocumentSaveClickHandler::Save(
itemFullId,
document,
true);
});
_contextMenu->addAction(
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 {
DocumentData *document = getShownDocument();
document->automaticLoad(nullptr);
const auto document = getShownDocument();
document->automaticLoad(fileOrigin(), nullptr);
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
if (loaded && !_gif && !_gif.isBad()) {
@ -286,25 +286,26 @@ QSize Gif::countFrameSize() 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->loaded()) {
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 {
document->thumb->load();
document->thumb->load(origin);
}
}
} else {
ImagePtr thumb = getResultThumb();
const auto thumb = getResultThumb();
if (!thumb->isNull()) {
if (thumb->loaded()) {
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 {
thumb->load();
thumb->load(origin);
}
}
}
@ -375,17 +376,9 @@ void Sticker::initDimensions() {
void Sticker::preload() const {
if (const auto document = getShownDocument()) {
const auto goodThumb = document->hasGoodStickerThumb();
if (goodThumb) {
document->thumb->load();
} else {
document->checkSticker();
}
} else {
const auto thumb = getResultThumb();
if (!thumb->isNull()) {
thumb->load();
}
document->checkStickerThumb();
} else if (const auto thumb = getResultThumb()) {
thumb->load(fileOrigin());
}
}
@ -441,33 +434,31 @@ QSize Sticker::getThumbSize() const {
void Sticker::prepareThumb() const {
if (const auto document = getShownDocument()) {
const auto goodThumb = document->hasGoodStickerThumb();
if (goodThumb) {
document->thumb->load();
} else {
document->checkSticker();
}
document->checkStickerThumb();
const auto sticker = goodThumb
? document->thumb
: document->sticker()
? document->sticker()->img
: ImagePtr();
const auto sticker = document->getStickerThumb();
if (!_thumbLoaded && !sticker->isNull() && sticker->loaded()) {
QSize thumbSize = getThumbSize();
_thumb = sticker->pix(thumbSize.width(), thumbSize.height());
const auto thumbSize = getThumbSize();
_thumb = sticker->pix(
document->stickerSetOrigin(),
thumbSize.width(),
thumbSize.height());
_thumbLoaded = true;
}
} else {
ImagePtr thumb = getResultThumb();
const auto origin = fileOrigin();
const auto thumb = getResultThumb();
if (thumb->loaded()) {
if (!_thumbLoaded) {
QSize thumbSize = getThumbSize();
_thumb = thumb->pix(thumbSize.width(), thumbSize.height());
const auto thumbSize = getThumbSize();
_thumb = thumb->pix(
origin,
thumbSize.width(),
thumbSize.height());
_thumbLoaded = true;
}
} 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 {
if (PhotoData *photo = getShownPhoto()) {
const auto origin = fileOrigin();
if (const auto photo = getShownPhoto()) {
if (photo->medium->loaded()) {
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;
} else {
if (photo->thumb->loaded()) {
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 {
ImagePtr thumb = getResultThumb();
const auto thumb = getResultThumb();
if (thumb->loaded()) {
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 {
thumb->load();
thumb->load(origin);
}
}
}
@ -660,7 +652,8 @@ TextState Video::getState(
}
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.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
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;
}
}
_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 {
thumb->load();
thumb->load(origin);
}
}
@ -971,7 +964,7 @@ TextState Contact::getState(
}
void Contact::prepareThumb(int width, int height) const {
ImagePtr thumb = getResultThumb();
const auto thumb = getResultThumb();
if (thumb->isNull()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = getResultContactAvatar(width, height);
@ -979,6 +972,7 @@ void Contact::prepareThumb(int width, int height) const {
return;
}
const auto origin = fileOrigin();
if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
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;
}
}
_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 {
thumb->load();
thumb->load(origin);
}
}
@ -1118,7 +1112,7 @@ TextState Article::getState(
}
void Article::prepareThumb(int width, int height) const {
ImagePtr thumb = getResultThumb();
const auto thumb = getResultThumb();
if (thumb->isNull()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
_thumb = getResultContactAvatar(width, height);
@ -1126,6 +1120,7 @@ void Article::prepareThumb(int width, int height) const {
return;
}
const auto origin = fileOrigin();
if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
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;
}
}
_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 {
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 animatedThumb = document && document->isAnimation();
if (animatedThumb) {
document->automaticLoad(nullptr);
document->automaticLoad(fileOrigin(), nullptr);
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
if (loaded && !_gif && !_gif.isBad()) {
@ -1293,7 +1288,7 @@ TextState Game::getState(
}
void Game::prepareThumb(int width, int height) const {
auto thumb = [this] {
const auto thumb = [this] {
if (auto photo = getResultPhoto()) {
return photo->medium;
} else if (auto document = getResultDocument()) {
@ -1305,6 +1300,7 @@ void Game::prepareThumb(int width, int height) const {
return;
}
const auto origin = fileOrigin();
if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
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;
}
}
_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 {
thumb->load();
thumb->load(origin);
}
}

View file

@ -68,18 +68,19 @@ PhotoData *ItemBase::getPreviewPhoto() const {
}
void ItemBase::preload() const {
const auto origin = fileOrigin();
if (_result) {
if (_result->_photo) {
_result->_photo->thumb->load();
_result->_photo->thumb->load(origin);
} else if (_result->_document) {
_result->_document->thumb->load();
_result->_document->thumb->load(origin);
} else if (!_result->_thumb->isNull()) {
_result->_thumb->load();
_result->_thumb->load(origin);
}
} else if (_doc) {
_doc->thumb->load();
_doc->thumb->load(origin);
} 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 bool inlineItemVisible(const ItemBase *item) = 0;
virtual void inlineItemRepaint(const ItemBase *item) = 0;
virtual Data::FileOrigin inlineItemFileOrigin() = 0;
};
class ItemBase : public LayoutItemBase {
@ -105,6 +106,9 @@ protected:
not_null<Context*> context() const {
return _context;
}
Data::FileOrigin fileOrigin() const {
return _context->inlineItemFileOrigin();
}
Result *_result = nullptr;
DocumentData *_doc = nullptr;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -710,7 +710,10 @@ void Mixer::play(
}
if (notLoadedYet) {
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 {
onError(audio);
}

View file

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

View file

@ -31,6 +31,20 @@ int Round(float64 value) {
using Context = GroupThumbs::Context;
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) {
Expects(index >= 0 && index < slice.size());
@ -96,7 +110,11 @@ public:
Dying,
};
Thumb(Key key, ImagePtr image, Fn<void()> handler);
Thumb(
Key key,
ImagePtr image,
Data::FileOrigin origin,
Fn<void()> handler);
int leftToUpdate() const;
int rightToUpdate() const;
@ -123,6 +141,7 @@ private:
ClickHandlerPtr _link;
const Key _key;
ImagePtr _image;
Data::FileOrigin _origin;
State _state = State::Alive;
QPixmap _full;
int _fullWidth = 0;
@ -137,9 +156,11 @@ private:
GroupThumbs::Thumb::Thumb(
Key key,
ImagePtr image,
Data::FileOrigin origin,
Fn<void()> handler)
: _key(key)
, _image(image) {
, _image(image)
, _origin(origin) {
_link = std::make_shared<LambdaClickHandler>(std::move(handler));
_fullWidth = std::min(
wantedPixSize().width(),
@ -159,7 +180,7 @@ void GroupThumbs::Thumb::validateImage() {
if (!_full.isNull()) {
return;
}
_image->load();
_image->load(_origin);
if (!_image->loaded()) {
return;
}
@ -170,7 +191,7 @@ void GroupThumbs::Thumb::validateImage() {
const auto originalHeight = _image->height();
const auto takeWidth = originalWidth * st::mediaviewGroupWidthMax
/ pixSize.width();
const auto original = _image->pixNoCache().toImage();
const auto original = _image->pixNoCache(_origin).toImage();
_full = App::pixmapFromImageInPlace(original.copy(
(originalWidth - takeWidth) / 2,
0,
@ -183,6 +204,7 @@ void GroupThumbs::Thumb::validateImage() {
Qt::SmoothTransformation));
} else {
_full = _image->pixNoCache(
_origin,
pixSize.width() * cIntRetinaFactor(),
pixSize.height() * cIntRetinaFactor(),
Images::Option::Smooth);
@ -396,7 +418,6 @@ void GroupThumbs::fillItems(
Expects(index < till);
Expects(from + 1 < till);
const auto current = (index - from);
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)) {
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)) {
if (const auto item = App::histItemById(*msgId)) {
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)
-> std::unique_ptr<Thumb> {
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()) {
strong->_activateStream.fire_copy(key);
}

View file

@ -843,7 +843,7 @@ void MediaView::onSaveAs() {
if (_doc->data().isEmpty()) location.accessDisable();
} else {
if (!fileShown()) {
DocumentSaveClickHandler::doSave(_doc, true);
DocumentSaveClickHandler::Save(fileOrigin(), _doc, true);
updateControls();
} else {
_saveVisible = false;
@ -868,7 +868,7 @@ void MediaView::onSaveAs() {
_photo->date),
crl::guard(this, [this, photo = _photo](const QString &result) {
if (!result.isEmpty() && _photo == photo && photo->loaded()) {
photo->full->pix().toImage().save(result, "JPG");
photo->full->pix(fileOrigin()).toImage().save(result, "JPG");
}
psShowOverAll(this);
}), crl::guard(this, [this] {
@ -884,7 +884,11 @@ void MediaView::onDocClick() {
if (_doc->loading()) {
onSaveCancel();
} else {
DocumentOpenClickHandler::doOpen(_doc, nullptr, ActionOnLoadNone);
DocumentOpenClickHandler::Open(
fileOrigin(),
_doc,
App::histItemById(_msgid),
ActionOnLoadNone);
if (_doc->loading() && !_radial.animating()) {
_radial.start(_doc->progress());
}
@ -971,7 +975,7 @@ void MediaView::onDownload() {
location.accessDisable();
} else {
if (!fileShown()) {
DocumentSaveClickHandler::doSave(_doc);
DocumentSaveClickHandler::Save(fileOrigin(), _doc);
updateControls();
} else {
_saveVisible = false;
@ -986,7 +990,7 @@ void MediaView::onDownload() {
} else {
if (!QDir().exists(path)) QDir().mkpath(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();
}
}
@ -1065,7 +1069,7 @@ void MediaView::onCopy() {
} else {
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;
}
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 {
if (auto key = sharedMediaKey()) {
if (!_sharedMedia) {
@ -1452,7 +1467,7 @@ void MediaView::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item) {
} else {
_from = _user;
}
_photo->download();
_photo->download(fileOrigin());
displayFinished();
}
@ -1493,12 +1508,15 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
if (_doc->sticker()) {
_doc->checkSticker();
if (!_doc->sticker()->img->isNull()) {
_current = _doc->sticker()->img->pix();
_current = _doc->sticker()->img->pix(fileOrigin());
} else {
_current = _doc->thumb->pixBlurred(_doc->dimensions.width(), _doc->dimensions.height());
_current = _doc->thumb->pixBlurred(
fileOrigin(),
_doc->dimensions.width(),
_doc->dimensions.height());
}
} else {
_doc->automaticLoad(item);
_doc->automaticLoad(fileOrigin(), item);
if (_doc->isAnimation() || _doc->isVideoFile()) {
initAnimation();
@ -1531,7 +1549,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
_docExtWidth = st::mediaviewFileNameFont->width(_docExt);
}
} else {
_doc->thumb->load();
_doc->thumb->load(fileOrigin());
int32 tw = _doc->thumb->width(), th = _doc->thumb->height();
if (!tw || !th) {
_docThumbx = _docThumby = _docThumbw = 0;
@ -1673,10 +1691,10 @@ void MediaView::initAnimation() {
} else if (_doc->dimensions.width() && _doc->dimensions.height()) {
auto w = _doc->dimensions.width();
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());
} 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()) {
int w = _doc->dimensions.width();
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());
} 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())
? Media::Clip::Reader::Mode::Video
@ -1957,20 +1975,20 @@ void MediaView::paintEvent(QPaintEvent *e) {
int32 w = _width * cIntRetinaFactor();
if (_full <= 0 && _photo->loaded()) {
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());
_full = 1;
} else if (_full < 0 && _photo->medium->loaded()) {
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());
_full = 0;
} else if (_current.isNull() && _photo->thumb->loaded()) {
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());
} else if (_current.isNull()) {
_current = _photo->thumb->pix();
_current = _photo->thumb->pix(fileOrigin());
}
}
p.setOpacity(1);
@ -2071,7 +2089,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
}
} else {
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);
@ -2571,13 +2589,13 @@ void MediaView::preloadData(int delta) {
for (auto index = from; index != till; ++index) {
auto entity = entityByIndex(index);
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)) {
if (auto sticker = (*document)->sticker()) {
sticker->img->load();
sticker->img->load(fileOrigin());
} else {
(*document)->thumb->load();
(*document)->automaticLoad(entity.item);
(*document)->thumb->load(fileOrigin());
(*document)->automaticLoad(fileOrigin(), entity.item);
}
}
}

View file

@ -175,6 +175,8 @@ private:
void validateUserPhotos();
void handleUserPhotosUpdate(UserPhotosSlice &&update);
Data::FileOrigin fileOrigin() const;
void refreshCaption(HistoryItem *item);
void refreshMediaViewer();
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) {
bool good = _data->loaded(), selected = (selection == FullSelection);
if (!good) {
_data->medium->automaticLoad(parent());
_data->medium->automaticLoad(parent()->fullId(), parent());
good = _data->medium->loaded();
}
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();
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) {
img = Images::prepareBlur(std::move(img));
}
@ -376,7 +376,7 @@ Video::Video(
, _duration(formatDurationText(_data->duration()))
, _thumbLoaded(false) {
setDocumentLinks(_data);
_data->thumb->load();
_data->thumb->load(parent->fullId());
}
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) {
bool selected = (selection == FullSelection), thumbLoaded = _data->thumb->loaded();
_data->automaticLoad(parent());
_data->automaticLoad(parent()->fullId(), parent());
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
if (displayLoading) {
ensureRadial();
@ -409,7 +409,7 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
if (_thumbLoaded && !_data->thumb->isNull()) {
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() != size) {
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) {
bool selected = (selection == FullSelection);
_data->automaticLoad(parent());
_data->automaticLoad(parent()->fullId(), parent());
bool loaded = _data->loaded(), displayLoading = _data->displayLoading();
if (displayLoading) {
@ -832,7 +832,7 @@ Document::Document(
_status.update(FileStatusSizeReady, _data->size, _data->isSong() ? _data->song()->duration : -1, 0);
if (withThumb()) {
_data->thumb->load();
_data->thumb->load(parent->fullId());
int32 tw = convertScale(_data->thumb->width()), th = convertScale(_data->thumb->height());
if (tw > 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) {
bool selected = (selection == FullSelection);
_data->automaticLoad(parent());
_data->automaticLoad(parent()->fullId(), parent());
bool loaded = _data->loaded() || Local::willStickerImageLoad(_data->mediaKey()), displayLoading = _data->displayLoading();
if (displayLoading) {
@ -936,7 +936,7 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
_thumbForLoaded = loaded;
auto options = Images::Option::Smooth | Images::Option::None;
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);
} else {
@ -1267,12 +1267,16 @@ Link::Link(
}
int32 tw = 0, th = 0;
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());
th = convertScale(_page->photo->thumb->height());
} 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());
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) {
QPixmap pix;
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()) {
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 {
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);
} else if (_page && _page->document && !_page->document->thumb->isNull()) {
auto roundRadius = _page->document->isVideoMessage()
? ImageRoundRadius::Ellipse
: 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 {
const auto index = _letter.isEmpty()
? 0

View file

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

View file

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

View file

@ -71,7 +71,7 @@ void BackgroundRow::paintEvent(QPaintEvent *e) {
if (backThumb->isNull()) {
p.drawPixmap(0, 0, _background);
} 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());
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -25,8 +25,9 @@ enum StickerSetType {
namespace Serialize {
void Document::writeToStream(QDataStream &stream, DocumentData *document) {
const auto version = 0;
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 << qint32(document->dimensions.width()) << qint32(document->dimensions.height());
stream << qint32(document->type);
@ -58,7 +59,11 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream &
QByteArray fileReference;
stream >> id >> access >> date;
if (streamAppVersion >= 9061) {
if (streamAppVersion >= 1003011) {
#ifdef _DEBUG
if (streamAppVersion >= 1003013 || true) { // #TODO testing
#else
#error "test"
#endif
stream >> fileReference;
}
stream >> version;
@ -131,7 +136,6 @@ DocumentData *Document::readFromStreamHelper(int streamAppVersion, QDataStream &
return Auth().data().document(
id,
access,
version,
fileReference,
date,
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options);
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -500,7 +503,12 @@ const QPixmap &Image::pix(int32 w, int32 h) const {
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options);
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -536,7 +544,10 @@ const QPixmap &Image::pixRounded(int32 w, int32 h, ImageRoundRadius radius, Rect
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options);
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -559,7 +570,10 @@ const QPixmap &Image::pixCircled(int32 w, int32 h) const {
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options);
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -582,7 +596,10 @@ const QPixmap &Image::pixBlurredCircled(int32 w, int32 h) const {
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixNoCache(w, h, options);
auto p = pixNoCache(origin, w, h, options);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -605,7 +622,11 @@ const QPixmap &Image::pixBlurred(int32 w, int32 h) const {
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixColoredNoCache(add, w, h, true);
auto p = pixColoredNoCache(origin, add, w, h, true);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -628,7 +649,11 @@ const QPixmap &Image::pixColored(style::color add, int32 w, int32 h) const {
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();
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 i = _sizesCache.constFind(k);
if (i == _sizesCache.cend()) {
auto p = pixBlurredColoredNoCache(add, w, h);
auto p = pixBlurredColoredNoCache(origin, add, w, h);
if (cRetina()) p.setDevicePixelRatio(cRetinaFactor());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -651,7 +676,15 @@ const QPixmap &Image::pixBlurredColored(style::color add, int32 w, int32 h) cons
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();
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()) {
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());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -695,7 +728,14 @@ const QPixmap &Image::pixSingle(int32 w, int32 h, int32 outerw, int32 outerh, Im
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();
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()) {
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());
i = _sizesCache.insert(k, p);
if (!p.isNull()) {
@ -736,15 +776,22 @@ const QPixmap &Image::pixBlurredSingle(int w, int h, int32 outerw, int32 outerh,
return i.value();
}
QPixmap Image::pixNoCache(int w, int h, Images::Options options, int outerw, int outerh, const style::color *colored) const {
if (!loading()) const_cast<Image*>(this)->load();
QPixmap Image::pixNoCache(
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();
if (_data.isNull()) {
if (h <= 0 && height() > 0) {
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) {
@ -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);
}
QPixmap Image::pixColoredNoCache(style::color add, int32 w, int32 h, bool smooth) const {
const_cast<Image*>(this)->load();
QPixmap Image::pixColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h,
bool smooth) const {
const_cast<Image*>(this)->load(origin);
restore();
if (_data.isNull()) return blank()->pix();
if (_data.isNull()) return blank()->pix(origin);
auto img = _data.toImage();
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)));
}
QPixmap Image::pixBlurredColoredNoCache(style::color add, int32 w, int32 h) const {
const_cast<Image*>(this)->load();
QPixmap Image::pixBlurredColoredNoCache(
Data::FileOrigin origin,
style::color add,
int32 w,
int32 h) const {
const_cast<Image*>(this)->load(origin);
restore();
if (_data.isNull()) return blank()->pix();
if (_data.isNull()) return blank()->pix(origin);
auto img = Images::prepareBlur(_data.toImage());
if (h <= 0) {
@ -933,7 +989,7 @@ void RemoteImage::destroyLoaderDelayed(FileLoader *newValue) const {
void RemoteImage::loadLocal() {
if (loaded() || amLoading()) return;
_loader = createLoader(LoadFromLocalOnly, true);
_loader = createLoader(base::none, LoadFromLocalOnly, true);
if (_loader) _loader->start();
}
@ -963,7 +1019,9 @@ bool RemoteImage::amLoading() const {
return _loader && _loader != CancelledFileLoader;
}
void RemoteImage::automaticLoad(const HistoryItem *item) {
void RemoteImage::automaticLoad(
Data::FileOrigin origin,
const HistoryItem *item) {
if (loaded()) return;
if (_loader != CancelledFileLoader && item) {
@ -977,7 +1035,10 @@ void RemoteImage::automaticLoad(const HistoryItem *item) {
if (_loader) {
if (loadFromCloud) _loader->permitLoadFromCloud();
} else {
_loader = createLoader(loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true);
_loader = createLoader(
origin,
loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly,
true);
if (_loader) _loader->start();
}
}
@ -988,20 +1049,28 @@ void RemoteImage::automaticLoadSettingsChanged() {
_loader = 0;
}
void RemoteImage::load(bool loadFirst, bool prior) {
void RemoteImage::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (loaded()) return;
if (!_loader) {
_loader = createLoader(LoadFromCloudOrLocal, false);
_loader = createLoader(origin, LoadFromCloudOrLocal, false);
}
if (amLoading()) {
_loader->start(loadFirst, prior);
}
}
void RemoteImage::loadEvenCancelled(bool loadFirst, bool prior) {
if (_loader == CancelledFileLoader) _loader = 0;
return load(loadFirst, prior);
void RemoteImage::loadEvenCancelled(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_loader == CancelledFileLoader) {
_loader = nullptr;
}
return load(origin, loadFirst, prior);
}
RemoteImage::~RemoteImage() {
@ -1070,9 +1139,17 @@ void StorageImage::setInformation(int32 size, int32 width, int32 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;
return new mtpFileLoader(&_location, _size, fromCloud, autoLoading);
return new mtpFileLoader(
&_location,
origin,
_size,
fromCloud,
autoLoading);
}
WebFileImage::WebFileImage(
@ -1116,10 +1193,16 @@ void WebFileImage::setInformation(int size, int width, int height) {
}
FileLoader *WebFileImage::createLoader(
Data::FileOrigin origin,
LoadFromCloudSetting fromCloud,
bool autoLoading) {
if (_location.isNull()) return 0;
return new mtpFileLoader(&_location, _size, fromCloud, autoLoading);
return _location.isNull()
? nullptr
: new mtpFileLoader(
&_location,
_size,
fromCloud,
autoLoading);
}
DelayedStorageImage::DelayedStorageImage() : StorageImage(StorageImageLocation())
@ -1143,12 +1226,13 @@ DelayedStorageImage::DelayedStorageImage(QByteArray &bytes)
}
void DelayedStorageImage::setStorageLocation(
Data::FileOrigin origin,
const StorageImageLocation location) {
_location = location;
if (_loadRequested) {
if (!_loadCancelled) {
if (_loadFromCloud) {
load();
load(origin);
} else {
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 (!_loadCancelled && item) {
bool loadFromCloud = false;
@ -1175,7 +1261,7 @@ void DelayedStorageImage::automaticLoad(const HistoryItem *item) {
}
}
} else {
StorageImage::automaticLoad(item);
StorageImage::automaticLoad(origin, item);
}
}
@ -1184,17 +1270,23 @@ void DelayedStorageImage::automaticLoadSettingsChanged() {
StorageImage::automaticLoadSettingsChanged();
}
void DelayedStorageImage::load(bool loadFirst, bool prior) {
void DelayedStorageImage::load(
Data::FileOrigin origin,
bool loadFirst,
bool prior) {
if (_location.isNull()) {
_loadRequested = _loadFromCloud = true;
} 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;
StorageImage::loadEvenCancelled(loadFirst, prior);
StorageImage::loadEvenCancelled(origin, loadFirst, prior);
}
bool DelayedStorageImage::displayLoading() const {
@ -1245,7 +1337,10 @@ void WebImage::setInformation(int32 size, int32 width, int32 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);
}

View file

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

View file

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

View file

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

View file

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