gif autoplay improved

This commit is contained in:
John Preston 2015-12-23 22:23:14 +03:00
parent 6170144fe9
commit b94533fcb2
18 changed files with 401 additions and 226 deletions

View File

@ -149,6 +149,7 @@ void StickerSetInner::paintEvent(QPaintEvent *e) {
} else {
bool already = !doc->already().isEmpty(), hasdata = !doc->data.isEmpty();
if (!already && !hasdata && !doc->loader && doc->status == FileReady) {
doc->openOnSave = 0;
doc->save(QString());
}
if (doc->sticker()->img->isNull() && (already || hasdata)) {

View File

@ -1333,6 +1333,7 @@ void StickerPanInner::paintEvent(QPaintEvent *e) {
} else {
bool already = !sticker->already().isEmpty(), hasdata = !sticker->data.isEmpty();
if (!already && !hasdata && !sticker->loader && sticker->status == FileReady) {
sticker->openOnSave = 0;
sticker->save(QString());
}
if (sticker->sticker()->img->isNull() && (already || hasdata)) {
@ -1522,6 +1523,7 @@ void StickerPanInner::preloadImages() {
} else {
bool already = !sticker->already().isEmpty(), hasdata = !sticker->data.isEmpty();
if (!already && !hasdata && !sticker->loader && sticker->status == FileReady) {
sticker->openOnSave = 0;
sticker->save(QString());
}
//if (sticker->sticker->img->isNull() && (already || hasdata)) {

View File

@ -3773,11 +3773,12 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool loaded = _data->loaded();
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->loading() && !_data->loader->paused()) {
if (!loaded && _data->status == FileReady && _data->loader && !_data->loadingStarted()) {
_data->openOnSave = 0;
_data->save(QString());
}
if (_data->loader && (_data->loader->loading() || _data->loader->paused())) {
if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureAnimation(parent);
if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress());
@ -3802,7 +3803,7 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
float64 over = _animation->a_thumbOver.current();
p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over));
} else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel);
bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg));
}
@ -3821,7 +3822,7 @@ void HistoryAudio::draw(Painter &p, const HistoryItem *parent, const QRect &r, b
icon = outbg ? (selected ? st::msgFileOutPauseSelected : st::msgFileOutPause) : (selected ? st::msgFileInPauseSelected : st::msgFileInPause);
} else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) {
icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else {
icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -3856,19 +3857,19 @@ void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
bool loaded = _data->loaded();
bool showPause = updateStatusText(parent);
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if ((_data->loader || _data->status == FileUploading || (!already && !hasdata)) && inner.contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _cancell : _savel;
if ((_data->loadingStarted() || _data->status == FileUploading || !loaded) && inner.contains(x, y)) {
lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel;
return;
}
if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loader && _data->access) {
if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loadingStarted() && _data->access) {
lnk = _openl;
return;
}
@ -3910,9 +3911,9 @@ bool HistoryAudio::updateStatusText(const HistoryItem *parent) const {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset();
} else if (!_data->already().isEmpty() || !_data->data.isEmpty()) {
} else if (_data->loaded()) {
AudioMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
@ -4002,9 +4003,9 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
bool loaded = _data->loaded();
if (_data->loader) {
if (_data->loadingStarted()) {
ensureAnimation(parent);
if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress());
@ -4024,7 +4025,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
if (_data->thumb->loaded()) {
QPixmap thumb = (already || hasdata) ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
QPixmap thumb = loaded ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
p.drawPixmap(rthumb.topLeft(), thumb);
} else {
App::roundRect(p, rthumb, st::black, BlackCorners);
@ -4033,13 +4034,12 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
if (!radial && (already || hasdata)) {
} else {
if (radial || !loaded) {
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen);
if (selected) {
p.setBrush(st::msgDateImgBgSelected);
} else if (radial && (already || hasdata)) {
} else if (radial && loaded) {
p.setOpacity(st::msgDateImgBg->c.alphaF() * _animation->radial.opacity());
p.setBrush(st::black);
} else if (_animation && _animation->_a_thumbOver.animating()) {
@ -4048,7 +4048,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
p.setBrush(st::black);
} else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel);
bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
}
@ -4057,7 +4057,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
style::sprite icon;
if (already || hasdata || _data->loader) {
if (loaded || _data->loadingStarted()) {
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else {
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -4073,7 +4073,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
}
if (_data->status != FileUploadFailed) {
const TextLinkPtr &lnk((_data->loader || _data->status == FileUploading) ? _linkcancell : _linksavel);
const TextLinkPtr &lnk((_data->loadingStarted() || _data->status == FileUploading) ? _linkcancell : _linksavel);
bool over = textlnkDrawOver(lnk);
p.setFont(over ? st::semiboldFont->underline() : st::semiboldFont);
p.setPen(outbg ? (selected ? st::msgFileThumbLinkOutFgSelected : st::msgFileThumbLinkOutFg) : (selected ? st::msgFileThumbLinkInFgSelected : st::msgFileThumbLinkInFg));
@ -4093,7 +4093,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
float64 over = _animation->a_thumbOver.current();
p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over));
} else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel);
bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(outbg ? (over ? st::msgFileOutBgOver : st::msgFileOutBg) : (over ? st::msgFileInBgOver : st::msgFileInBg));
}
@ -4118,7 +4118,7 @@ void HistoryDocument::draw(Painter &p, const HistoryItem *parent, const QRect &r
} else {
icon = outbg ? (selected ? st::msgFileOutFileSelected : st::msgFileOutFile) : (selected ? st::msgFileInFileSelected : st::msgFileInFile);
}
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
icon = outbg ? (selected ? st::msgFileOutCancelSelected : st::msgFileOutCancel) : (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else {
icon = outbg ? (selected ? st::msgFileOutDownloadSelected : st::msgFileOutDownload) : (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -4145,7 +4145,7 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
if (_width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
bool loaded = _data->loaded();
bool showPause = updateStatusText(parent);
@ -4157,28 +4157,28 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
if (already || hasdata) {
if (loaded) {
} else {
if (rthumb.contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _cancell : _savel;
lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel;
return;
}
}
if (_data->status != FileUploadFailed) {
if (rtlrect(nameleft, linktop, _linkw, st::semiboldFont->height, _width).contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _linkcancell : _linksavel;
lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _linkcancell : _linksavel;
return;
}
}
} else {
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if ((_data->loader || _data->status == FileUploading || (!already && !hasdata)) && inner.contains(x, y)) {
lnk = (_data->loader || _data->status == FileUploading) ? _cancell : _savel;
if ((_data->loadingStarted() || _data->status == FileUploading || !loaded) && inner.contains(x, y)) {
lnk = (_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel;
return;
}
}
if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loader && _data->access) {
if (x >= 0 && y >= 0 && x < _width && y < _height && !_data->loadingStarted() && _data->access) {
lnk = _openl;
return;
}
@ -4216,29 +4216,31 @@ bool HistoryDocument::updateStatusText(const HistoryItem *parent) const {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset();
} else if (_data->song() && (!_data->already().isEmpty() || !_data->data.isEmpty())) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) {
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
} else if (_data->loaded()) {
if (_data->song()) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) {
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
if (playing.msgId == parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && playing.msgId == parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else if (!_data->already().isEmpty() || !_data->data.isEmpty()) {
statusSize = FileStatusSizeLoaded;
} else {
statusSize = FileStatusSizeReady;
}
@ -4394,7 +4396,8 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel;
bool loaded = _data->loaded(_gif ? false : true);
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->loading() && !_data->loader->paused()) {
if (!loaded && _data->status == FileReady && _data->loader && !_data->loadingStarted()) {
_data->openOnSave = 0;
_data->save(QString());
}
if (loaded && !_gif) {
@ -4404,7 +4407,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
bool animating = (_gif && _gif->started());
if (!animating) {
if (_data->loader && !_data->loader->tryingLocal()) {
if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureAnimation(parent);
if (!_animation->radial.animating()) {
_animation->radial.start(_data->progress());
@ -4436,7 +4439,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
if (radial || (!animating && !_gif && (!_data->loader || !_data->loader->tryingLocal() || _data->size > AnimationInMemory))) {
if (radial || (!animating && !_gif && (!_data->loader || !_data->loader->loadingLocal() || _data->size > AnimationInMemory))) {
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
p.setPen(Qt::NoPen);
if (selected) {
@ -4447,7 +4450,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
p.setBrush(st::black);
} else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel);
bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
}
@ -4462,7 +4465,7 @@ void HistoryGif::draw(Painter &p, const HistoryItem *parent, const QRect &r, boo
style::sprite icon;
if (_data->loaded() && !radial) {
icon = (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
} else if (_data->loader || radial) {
} else if (_data->loadingStarted() || radial) {
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else {
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -4505,7 +4508,7 @@ void HistoryGif::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x,
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
if (_gif && _gif->started()) {
} else {
lnk = _data->loaded() ? _savel : (_data->loader ? _cancell : _savel);
lnk = _data->loaded() ? _savel : (_data->loadingStarted() ? _cancell : _savel);
}
if (parent->getMedia() == this) {
@ -4538,7 +4541,7 @@ void HistoryGif::updateStatusText(const HistoryItem *parent) const {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset();
} else if (_data->loaded()) {
statusSize = FileStatusSizeLoaded;
@ -4636,7 +4639,8 @@ void HistorySticker::draw(Painter &p, const HistoryItem *parent, const QRect &r,
bool out = parent->out(), fromChannel = parent->fromChannel(), outbg = out && !fromChannel, hovered, pressed;
bool loaded = _data->loaded();
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->loading() && !_data->loader->paused()) {
if (!loaded && _data->status == FileReady && _data->loader && !_data->loader->started()) {
_data->openOnSave = 0;
_data->save(QString());
}

View File

@ -880,7 +880,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(lng_context_save_image), this, SLOT(saveContextImage()))->setEnabled(true);
_menu->addAction(lang(lng_context_copy_image), this, SLOT(copyContextImage()))->setEnabled(true);
} else {
if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loader) || (lnkDocument && lnkDocument->document()->loader)) {
if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loadingStarted()) || (lnkDocument && lnkDocument->document()->loadingStarted())) {
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
} else {
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
@ -1063,12 +1063,15 @@ void HistoryInner::showContextInFolder() {
}
void HistoryInner::openContextFile() {
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
HistoryItem *was = App::hoveredLinkItem();
App::hoveredLinkItem(App::contextItem());
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton);
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
App::hoveredLinkItem(was);
}
void HistoryInner::saveContextFile() {

View File

@ -275,6 +275,7 @@ QPixmap StickerPreviewWidget::currentImage() const {
if (_doc && _cacheStatus != CacheLoaded) {
bool already = !_doc->already().isEmpty(), hasdata = !_doc->data.isEmpty();
if (!already && !hasdata && !_doc->loader && _doc->status == FileReady) {
_doc->openOnSave = 0;
_doc->save(QString());
}
if (_doc->sticker()->img->isNull() && (already || hasdata)) {

View File

@ -551,13 +551,13 @@ void LayoutOverviewAudio::initDimensions() {
void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
bool selected = (selection == FullSelection);
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
if (!_data->loader && _data->status == FileReady && !already && !hasdata && _data->size < AudioVoiceMsgInMemory) {
bool loaded = _data->loaded();
if (!loaded && _data->status == FileReady && _data->loader && !_data->loadingStarted()) {
_data->openOnSave = 0;
_data->save(QString());
}
if (_data->loader) {
if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureRadial();
if (!_radial->animating()) {
_radial->start(_data->progress());
@ -591,7 +591,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
float64 over = a_iconOver.current();
p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over));
} else {
bool over = textlnkDrawOver((already || hasdata) ? _openl : (_data->loader ? _cancell : _savel));
bool over = textlnkDrawOver(loaded ? _openl : (_data->loadingStarted() ? _cancell : _savel));
p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg);
}
@ -610,7 +610,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
icon = selected ? st::msgFileInPauseSelected : st::msgFileInPause;
} else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) {
icon = selected ? st::msgFileInPlaySelected : st::msgFileInPlay;
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
icon = selected ? st::msgFileInCancelSelected : st::msgFileInCancel;
} else {
icon = selected ? st::msgFileInDownloadSelected : st::msgFileInDownload;
@ -639,7 +639,7 @@ void LayoutOverviewAudio::paint(Painter &p, const QRect &clip, uint32 selection,
}
void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
bool loaded = _data->loaded();
bool showPause = updateStatusText();
@ -652,7 +652,7 @@ void LayoutOverviewAudio::getState(TextLinkPtr &link, HistoryCursorState &cursor
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if (inner.contains(x, y)) {
link = (already || hasdata) ? _openl : ((_data->loader || _data->status == FileUploading) ? _cancell : _savel);
link = loaded ? _openl : ((_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel);
return;
}
if (rtlrect(nameleft, statustop, _width - nameleft - nameright, st::normalFont->height, _width).contains(x, y)) {
@ -709,6 +709,7 @@ bool LayoutOverviewAudio::updateStatusText() const {
LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent) : LayoutAbstractFileItem(parent)
, _data(document)
, _msgl(new MessageLink(parent))
, _namel(new DocumentOpenLink(_data))
, _name(documentName(_data))
, _date(langDateTime(date(_data->date)))
, _namew(st::semiboldFont->width(_name))
@ -748,8 +749,8 @@ void LayoutOverviewDocument::initDimensions() {
void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
bool selected = (selection == FullSelection);
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
if (_data->loader) {
bool loaded = _data->loaded() || (_data->loader && _data->loader->localAvailable());
if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
ensureRadial();
if (!_radial->animating()) {
_radial->start(_data->progress());
@ -780,7 +781,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
float64 over = a_iconOver.current();
p.setBrush(style::interpolate(st::msgFileInBg, st::msgFileInBgOver, over));
} else {
bool over = textlnkDrawOver(already ? _openl : (_data->loader ? _cancell : _savel));
bool over = textlnkDrawOver(loaded ? _openl : (_data->loadingStarted() ? _cancell : _savel));
p.setBrush(over ? st::msgFileInBgOver : st::msgFileInBg);
}
@ -799,7 +800,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
icon = selected ? st::msgFileInPauseSelected : st::msgFileInPause;
} else if (_statusSize < 0 || _statusSize == FileStatusSizeLoaded) {
icon = selected ? st::msgFileInPlaySelected : st::msgFileInPlay;
} else if (_data->loader) {
} else if (_data->loadingStarted() && !_data->loader->loadingLocal()) {
icon = selected ? st::msgFileInCancelSelected : st::msgFileInCancel;
} else {
icon = selected ? st::msgFileInDownloadSelected : st::msgFileInDownload;
@ -821,14 +822,14 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
if (clip.intersects(rthumb)) {
if (wthumb) {
if (_data->thumb->loaded()) {
QPixmap thumb = (already || hasdata) ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
QPixmap thumb = loaded ? _data->thumb->pixSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize) : _data->thumb->pixBlurredSingle(_thumbw, 0, st::msgFileThumbSize, st::msgFileThumbSize);
p.drawPixmap(rthumb.topLeft(), thumb);
} else {
App::roundRect(p, rthumb, st::black, BlackCorners);
}
} else {
App::roundRect(p, rthumb, documentColor(_colorIndex), documentCorners(_colorIndex));
if (!radial && (already || hasdata)) {
if (!radial && loaded) {
style::sprite icon = documentCorner(_colorIndex);
p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - icon.pxWidth()), 0), icon);
if (!_ext.isEmpty()) {
@ -842,14 +843,13 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners);
}
if (!radial && (already || hasdata)) {
} else {
if (radial || (!loaded && !_data->loadingStarted())) {
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
if (clip.intersects(inner)) {
p.setPen(Qt::NoPen);
if (selected) {
p.setBrush(st::msgDateImgBgSelected);
} else if (radial && (already || hasdata)) {
} else if (radial && loaded) {
p.setOpacity(st::msgDateImgBg->c.alphaF() * _radial->opacity());
p.setBrush(st::black);
} else if (_a_iconOver.animating()) {
@ -858,7 +858,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
p.setOpacity((st::msgDateImgBg->c.alphaF() * (1 - over)) + (st::msgDateImgBgOver->c.alphaF() * over));
p.setBrush(st::black);
} else {
bool over = textlnkDrawOver(_data->loader ? _cancell : _savel);
bool over = textlnkDrawOver(_data->loadingStarted() ? _cancell : _savel);
p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg);
}
@ -867,7 +867,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
style::sprite icon;
if (already || hasdata || _data->loader) {
if (loaded || (_data->loadingStarted() && !_data->loader->loadingLocal())) {
icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel);
} else {
icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload);
@ -915,7 +915,7 @@ void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selecti
}
void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty();
bool loaded = _data->loaded() || (_data->loader && _data->loader->localAvailable());
bool showPause = updateStatusText();
@ -930,7 +930,7 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, _width));
if (inner.contains(x, y)) {
link = (already || hasdata) ? _openl : ((_data->loader || _data->status == FileUploading) ? _cancell : _savel);
link = loaded ? _openl : ((_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel);
return;
}
} else {
@ -941,12 +941,9 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width));
if (already || hasdata) {
} else {
if (rthumb.contains(x, y)) {
link = (_data->loader || _data->status == FileUploading) ? _cancell : _savel;
return;
}
if (rthumb.contains(x, y)) {
link = loaded ? _openl : ((_data->loadingStarted() || _data->status == FileUploading) ? _cancell : _savel);
return;
}
if (_data->status != FileUploadFailed) {
@ -955,13 +952,13 @@ void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cur
return;
}
}
if (!_data->loader && _data->access) {
if (rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(x, y)) {
link = _openl;
if (!_data->loadingStarted() && _data->access) {
if (loaded && rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(x, y)) {
link = _namel;
return;
}
if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _namew), st::semiboldFont->height, _width).contains(x, y)) {
link = _openl;
link = _namel;
return;
}
}
@ -975,29 +972,31 @@ bool LayoutOverviewDocument::updateStatusText() const {
statusSize = FileStatusSizeFailed;
} else if (_data->status == FileUploading) {
statusSize = _data->uploadOffset;
} else if (_data->loader) {
} else if (_data->loadingStarted()) {
statusSize = _data->loader->currentOffset();
} else if (_data->song() && (!_data->already().isEmpty() || !_data->data.isEmpty())) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) {
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
} else if (_data->loaded()) {
if (_data->song()) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
int64 playingPosition = 0, playingDuration = 0;
int32 playingFrequency = 0;
if (audioPlayer()) {
audioPlayer()->currentState(&playing, &playingState, &playingPosition, &playingDuration, &playingFrequency);
}
if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
if (playing.msgId == _parent->fullId() && !(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing) {
statusSize = -1 - (playingPosition / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency));
realDuration = playingDuration / (playingFrequency ? playingFrequency : AudioVoiceMsgFrequency);
showPause = (playingState == AudioPlayerPlaying || playingState == AudioPlayerResuming || playingState == AudioPlayerStarting);
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && playing.msgId == _parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else {
statusSize = FileStatusSizeLoaded;
}
if (!showPause && playing.msgId == _parent->fullId() && App::main() && App::main()->player()->seekingSong(playing)) {
showPause = true;
}
} else if (!_data->already().isEmpty() || !_data->data.isEmpty()) {
statusSize = FileStatusSizeLoaded;
} else {
statusSize = FileStatusSizeReady;
}

View File

@ -410,7 +410,7 @@ protected:
return !_data->loader;
}
virtual bool dataLoaded() const {
return !_data->already().isEmpty() || !_data->data.isEmpty();
return _data->loaded();
}
virtual bool iconAnimated() const {
return _data->song() || !dataLoaded() || (_radial && _radial->animating());
@ -419,7 +419,7 @@ protected:
private:
OverviewItemInfo _info;
DocumentData *_data;
TextLinkPtr _msgl;
TextLinkPtr _msgl, _namel;
QString _name, _date, _ext;
int32 _namew, _datew, _extw;

View File

@ -2411,13 +2411,17 @@ namespace Local {
};
TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader) {
StorageMap::iterator j = _imagesMap.find(location);
StorageMap::const_iterator j = _imagesMap.constFind(location);
if (j == _imagesMap.cend() || !_localLoader) {
return 0;
}
return _localLoader->addTask(new ImageLoadTask(j->first, location, loader));
}
bool willImageLoad(const StorageKey &location) {
return (_imagesMap.constFind(location) != _imagesMap.cend());
}
int32 hasImages() {
return _imagesMap.size();
}
@ -2470,13 +2474,17 @@ namespace Local {
};
TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader) {
StorageMap::iterator j = _stickerImagesMap.find(location);
StorageMap::const_iterator j = _stickerImagesMap.constFind(location);
if (j == _stickerImagesMap.cend() || !_localLoader) {
return 0;
}
return _localLoader->addTask(new StickerImageLoadTask(j->first, location, loader));
}
bool willStickerImageLoad(const StorageKey &location) {
return (_stickerImagesMap.constFind(location) != _stickerImagesMap.cend());
}
int32 hasStickers() {
return _stickerImagesMap.size();
}
@ -2529,13 +2537,17 @@ namespace Local {
};
TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader) {
StorageMap::iterator j = _audiosMap.find(location);
StorageMap::const_iterator j = _audiosMap.constFind(location);
if (j == _audiosMap.cend() || !_localLoader) {
return 0;
}
return _localLoader->addTask(new AudioLoadTask(j->first, location, loader));
}
bool willAudioLoad(const StorageKey &location) {
return (_audiosMap.constFind(location) != _audiosMap.cend());
}
int32 hasAudios() {
return _audiosMap.size();
}

View File

@ -124,16 +124,19 @@ namespace Local {
void writeImage(const StorageKey &location, const ImagePtr &img);
void writeImage(const StorageKey &location, const StorageImageSaved &jpeg, bool overwrite = true);
TaskId startImageLoad(const StorageKey &location, mtpFileLoader *loader);
bool willImageLoad(const StorageKey &location);
int32 hasImages();
qint64 storageImagesSize();
void writeStickerImage(const StorageKey &location, const QByteArray &data, bool overwrite = true);
TaskId startStickerImageLoad(const StorageKey &location, mtpFileLoader *loader);
bool willStickerImageLoad(const StorageKey &location);
int32 hasStickers();
qint64 storageStickersSize();
void writeAudio(const StorageKey &location, const QByteArray &data, bool overwrite = true);
TaskId startAudioLoad(const StorageKey &location, mtpFileLoader *loader);
bool willAudioLoad(const StorageKey &location);
int32 hasAudios();
qint64 storageAudiosSize();

View File

@ -1853,9 +1853,10 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
QString already = document->already();
HistoryItem *item = (document->openOnSave && document->openOnSaveMsgId.msg) ? App::histItemById(document->openOnSaveMsgId) : 0;
bool play = document->song() && audioPlayer() && document->openOnSave && item;
if ((!already.isEmpty() || (!document->data.isEmpty() && play)) && document->openOnSave) {
if (play) {
bool playMusic = document->song() && audioPlayer() && document->openOnSave && item;
bool playAnimation = document->isAnimation() && document->openOnSave > 0 && item && item->getMedia();
if (document->openOnSave && (!already.isEmpty() || (!document->data.isEmpty() && (playMusic || playAnimation)))) {
if (playMusic) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState);
@ -1869,22 +1870,32 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) {
songPlayActivated = true;
} else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) {
const FileLocation &location(document->location(true));
if (location.accessEnable()) {
if (!document->data.isEmpty() && playAnimation) {
if (document->openOnSave > 1) {
if (!item || !item->getMedia() || !item->getMedia()->playInline(item)) {
psOpenFile(already);
}
item->getMedia()->playInline(item);
} else {
if (item && (document->isAnimation() || QImageReader(location.name()).canRead())) {
App::wnd()->showDocument(document, item);
} else {
psOpenFile(already);
}
App::wnd()->showDocument(document, item);
}
location.accessDisable();
} else {
psOpenFile(already);
const FileLocation &location(document->location(true));
if (location.accessEnable()) {
if (document->openOnSave > 1) {
if (playAnimation) {
item->getMedia()->playInline(item);
} else {
psOpenFile(already);
}
} else {
if (playAnimation || (item && QImageReader(location.name()).canRead())) {
App::wnd()->showDocument(document, item);
} else {
psOpenFile(already);
}
}
location.accessDisable();
} else {
psOpenFile(already);
}
}
} else {
QPoint pos(QCursor::pos());

View File

@ -252,6 +252,11 @@ bool MediaView::gifShown() const {
return false;
}
void MediaView::stopGif() {
delete _gif;
_gif = 0;
}
void MediaView::documentUpdated(DocumentData *doc) {
if (_doc && _doc == doc && !fileShown()) {
if ((_doc->loader && _docCancel.isHidden()) || (!_doc->loader && !_docCancel.isHidden())) {
@ -314,15 +319,15 @@ void MediaView::updateControls() {
if (!_a_state.animating()) _a_state.start();
_a_state.step();
} else {
if (_doc->already(true).isEmpty()) {
_docDownload.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docDownload.show();
_docSaveAs.moveToLeft(_docRect.x() + 2.5 * st::mvDocPadding + st::mvDocIconSize + _docDownload.width(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
if (_doc->loaded(true)) {
_docDownload.hide();
_docSaveAs.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docSaveAs.show();
_docCancel.hide();
} else {
_docDownload.hide();
_docSaveAs.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docDownload.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docDownload.show();
_docSaveAs.moveToLeft(_docRect.x() + 2.5 * st::mvDocPadding + st::mvDocIconSize + _docDownload.width(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop);
_docSaveAs.show();
_docCancel.hide();
}
@ -334,7 +339,7 @@ void MediaView::updateControls() {
_docCancel.hide();
}
_saveVisible = ((_photo && _photo->full->loaded()) || (_doc && (!_doc->already(true).isEmpty() || (!fileShown() && (_photo || _doc)))));
_saveVisible = ((_photo && _photo->full->loaded()) || (_doc && (_doc->loaded(true) || (!fileShown() && (_photo || _doc)))));
_saveNav = myrtlrect(width() - st::mvIconSize.width() * 2, height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height());
_saveNavIcon = centersprite(_saveNav, st::mvSave);
_moreNav = myrtlrect(width() - st::mvIconSize.width(), height() - st::mvIconSize.height(), st::mvIconSize.width(), st::mvIconSize.height());
@ -445,7 +450,7 @@ void MediaView::step_state(uint64 ms, bool timer) {
if (dt < 1) result = true;
}
if (_doc && _docRadialStart > 0) {
float64 prg = _doc->loader ? qMax(_doc->loader->currentProgress(), 0.0001) : (_doc->status == FileDownloadFailed ? 0 : (_doc->already().isEmpty() ? 0 : 1));
float64 prg = _doc->loader ? qMax(_doc->loader->currentProgress(), 0.0001) : (_doc->status == FileDownloadFailed ? 0 : (_doc->loaded() ? 1 : 0));
if (prg != a_docRadial.to()) {
a_docRadial.start(prg);
_docRadialStart = _docRadialLast;
@ -457,18 +462,22 @@ void MediaView::step_state(uint64 ms, bool timer) {
if (_doc->loader) {
a_docRadial.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
result = true;
} else if (dt >= st::radialDuration) {
} else if (dt >= st::radialDuration || (_doc->loaded() && _doc->size < MediaViewImageSizeLimit && _doc->isAnimation())) {
a_docRadial.update(1, anim::linear);
result = true;
_docRadialFirst = _docRadialLast = _docRadialStart = 0;
a_docRadial = anim::fvalue(0, 0);
if (!_doc->already().isEmpty() && _doc->size < MediaViewImageSizeLimit) {
const FileLocation &location(_doc->location(true));
if (location.accessEnable()) {
if (QImageReader(location.name()).canRead()) {
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
if (_doc->loaded() && _doc->size < MediaViewImageSizeLimit) {
if (!_doc->data.isEmpty() && _doc->isAnimation()) {
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
} else {
const FileLocation &location(_doc->location(true));
if (location.accessEnable()) {
if (QImageReader(location.name()).canRead()) {
displayDocument(_doc, App::histItemById(_msgmigrated ? 0 : _channel, _msgid));
}
location.accessDisable();
}
location.accessDisable();
}
}
} else {
@ -547,7 +556,7 @@ void MediaView::onSaveAs() {
QString file;
if (_doc) {
const FileLocation &location(_doc->location(true));
if (location.accessEnable()) {
if (!_doc->data.isEmpty() || location.accessEnable()) {
QFileInfo alreadyInfo(location.name());
QDir alreadyDir(alreadyInfo.dir());
QString name = alreadyInfo.fileName(), filter;
@ -568,10 +577,16 @@ void MediaView::onSaveAs() {
file = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, true, alreadyDir);
psShowOverAll(this);
if (!file.isEmpty() && file != location.name()) {
QFile(location.name()).copy(file);
if (_doc->data.isEmpty()) {
QFile(location.name()).copy(file);
} else {
QFile f(file);
f.open(QIODevice::WriteOnly);
f.write(_doc->data);
}
}
location.accessDisable();
if (_doc->data.isEmpty()) location.accessDisable();
} else {
if (!fileShown()) {
DocumentSaveLink::doSave(_doc, true);
@ -626,8 +641,7 @@ void MediaView::notify_clipReinit(ClipReader *reader) {
}
displayDocument(_doc, item);
} else {
delete _gif;
_gif = 0;
stopGif();
}
}
}
@ -882,10 +896,9 @@ void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
}
void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
stopGif();
_doc = 0;
_photo = photo;
delete _gif;
_gif = 0;
_zoom = 0;
@ -939,8 +952,7 @@ void MediaView::displayPhoto(PhotoData *photo, HistoryItem *item) {
void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty messages shown as docs: doc can be NULL
if (!doc || !doc->isAnimation() || doc != _doc || (item && (item->id != _msgid || (item->history() != (_msgmigrated ? _migrated : _history))))) {
delete _gif;
_gif = 0;
stopGif();
}
_doc = doc;
_photo = 0;
@ -949,9 +961,21 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty
_caption = Text();
if (_doc) {
if (_doc->isAnimation() && !_doc->loaded() && _doc->status == FileReady && _doc->loader && !_doc->loadingStarted()) {
_doc->openOnSave = 0;
_doc->save(QString());
}
const FileLocation &location(_doc->location(true));
if (_doc->sticker() && !_doc->sticker()->img->isNull() && _doc->sticker()->img->loaded()) {
_current = _doc->sticker()->img->pix();
} else if (!_doc->data.isEmpty() && _doc->isAnimation()) {
if (!_gif) {
if (_doc->dimensions.width() && _doc->dimensions.height()) {
_current = _doc->thumb->pixNoCache(_doc->dimensions.width(), _doc->dimensions.height(), true, true, false, _doc->dimensions.width(), _doc->dimensions.height());
}
_gif = new ClipReader(location, _doc->data);
}
} else if (location.accessEnable()) {
if (_doc->isAnimation()) {
if (!_gif) {
@ -1195,7 +1219,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
icon = true;
if (!_doc || _doc->thumb->isNull()) {
p.fillRect(_docIconRect, _docIconColor->b);
if ((!_doc || !_doc->already().isEmpty()) && (!_docRadialStart || _docRadialOpacity < 1)) {
if ((!_doc || _doc->loaded()) && (!_docRadialStart || _docRadialOpacity < 1)) {
p.drawSprite(_docIconRect.topLeft() + QPoint(rtl() ? 0 : (_docIconRect.width() - _docIcon.pxWidth()), 0), _docIcon);
p.setPen(st::mvDocExtColor->p);
p.setFont(st::mvDocExtFont->f);
@ -1210,7 +1234,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
float64 o = overLevel(OverIcon);
if (_doc && _docRadialStart > 0) {
if (_doc->already().isEmpty() && _docRadialOpacity < 1) {
if (!_doc->loaded() && _docRadialOpacity < 1) {
p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity) * (1 - _docRadialOpacity));
p.drawSpriteCenter(_docIconRect, st::radialDownload);
}
@ -1236,7 +1260,7 @@ void MediaView::paintEvent(QPaintEvent *e) {
p.setOpacity(1);
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
} else if (_doc && _doc->already().isEmpty()) {
} else if (_doc && !_doc->loaded()) {
p.setOpacity((o * 1. + (1 - o) * st::radialDownloadOpacity));
p.drawSpriteCenter(_docIconRect, st::radialDownload);
}
@ -1505,8 +1529,7 @@ void MediaView::moveToNext(int32 delta) {
_channel = _history ? _history->channelId() : NoChannel;
_canForward = _msgid > 0;
_canDelete = item->canDelete();
delete _gif;
_gif = 0;
stopGif();
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: displayPhoto(static_cast<HistoryPhoto*>(item->getMedia())->photo(), item); preloadData(delta); break;
@ -1541,31 +1564,6 @@ void MediaView::preloadData(int32 delta) {
int32 from = _index + (delta ? delta : -1), to = _index + (delta ? delta * MediaOverviewPreloadCount : 1);
if (from > to) qSwap(from, to);
if (_history && _overview != OverviewCount) {
for (int32 i = from; i <= to; ++i) {
History *previewHistory = _msgmigrated ? _migrated : _history;
int32 previewIndex = i;
if (_migrated) {
if (_msgmigrated && previewIndex >= _migrated->overview[_overview].size()) {
previewHistory = _history;
previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
} else if (!_msgmigrated && previewIndex < 0) {
previewHistory = _migrated;
previewIndex += _migrated->overview[_overview].size();
}
}
if (previewIndex >= 0 && previewIndex < previewHistory->overview[_overview].size() && (previewHistory != (_msgmigrated ? _migrated : _history) || previewIndex != _index)) {
if (HistoryItem *item = App::histItemById(previewHistory->channelId(), previewHistory->overview[_overview][previewIndex])) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
case MediaTypeDocument:
case MediaTypeGif: static_cast<HistoryGif*>(media)->getDocument()->thumb->load(); break;
case MediaTypeSticker: static_cast<HistorySticker*>(media)->getDocument()->sticker()->img->load(); break;
}
}
}
}
}
int32 forgetIndex = _index - delta * 2;
History *forgetHistory = _msgmigrated ? _migrated : _history;
if (_migrated) {
@ -1584,7 +1582,47 @@ void MediaView::preloadData(int32 delta) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->forget(); break;
case MediaTypeDocument:
case MediaTypeGif:
case MediaTypeSticker: media->getDocument()->forget(); break;
case MediaTypeSticker:
DocumentData *doc = media->getDocument();
doc->forget();
if (!doc->data.isEmpty()) {
doc->data.clear();
doc->prepareAutoLoader();
}
break;
}
}
}
}
for (int32 i = from; i <= to; ++i) {
History *previewHistory = _msgmigrated ? _migrated : _history;
int32 previewIndex = i;
if (_migrated) {
if (_msgmigrated && previewIndex >= _migrated->overview[_overview].size()) {
previewHistory = _history;
previewIndex -= _migrated->overview[_overview].size() + (_history->overviewCount(_overview) - _history->overview[_overview].size());
} else if (!_msgmigrated && previewIndex < 0) {
previewHistory = _migrated;
previewIndex += _migrated->overview[_overview].size();
}
}
if (previewIndex >= 0 && previewIndex < previewHistory->overview[_overview].size() && (previewHistory != (_msgmigrated ? _migrated : _history) || previewIndex != _index)) {
if (HistoryItem *item = App::histItemById(previewHistory->channelId(), previewHistory->overview[_overview][previewIndex])) {
if (HistoryMedia *media = item->getMedia()) {
switch (media->type()) {
case MediaTypePhoto: static_cast<HistoryPhoto*>(media)->photo()->full->load(); break;
case MediaTypeDocument:
case MediaTypeGif: {
DocumentData *doc = media->getDocument();
doc->thumb->load();
if (doc->isAnimation() && !doc->loaded() && doc->status == FileReady && doc->loader && !doc->loadingStarted()) {
doc->openOnSave = 0;
doc->save(QString());
}
} break;
case MediaTypeSticker: media->getDocument()->sticker()->img->load(); break;
}
}
}
}
@ -1950,8 +1988,7 @@ void MediaView::hide() {
_controlsState = ControlsShown;
a_cOpacity = anim::fvalue(1, 1);
QWidget::hide();
delete _gif;
_gif = 0;
stopGif();
}
void MediaView::onMenuDestroy(QObject *obj) {

View File

@ -146,6 +146,7 @@ private:
bool fileShown() const;
bool gifShown() const;
void stopGif();
style::sprite _docIcon;
style::color _docIconColor;

View File

@ -47,11 +47,28 @@ namespace {
LoaderQueues queues;
}
mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &volume, int32 local, const uint64 &secret, int32 size) : prev(0), next(0),
priority(0), _paused(false), inQueue(false), complete(false),
_localStatus(LocalNotTried), skippedBytes(0), nextRequestOffset(0), lastComplete(false),
dc(dc), _locationType(UnknownFileLocation), volume(volume), local(local), secret(secret),
id(0), access(0), fileIsOpen(false), size(size), type(mtpc_storage_fileUnknown), _localTaskId(0) {
mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &volume, int32 local, const uint64 &secret, int32 size)
: prev(0)
, next(0)
, priority(0)
, _paused(false)
, inQueue(false)
, complete(false)
, _localStatus(LocalNotTried)
, skippedBytes(0)
, nextRequestOffset(0)
, lastComplete(false)
, dc(dc)
, _locationType(UnknownFileLocation)
, volume(volume)
, local(local)
, secret(secret)
, id(0)
, access(0)
, fileIsOpen(false)
, size(size)
, type(mtpc_storage_fileUnknown)
, _localTaskId(0) {
LoaderQueues::iterator i = queues.find(dc);
if (i == queues.cend()) {
i = queues.insert(dc, mtpFileLoaderQueue());
@ -59,11 +76,31 @@ id(0), access(0), fileIsOpen(false), size(size), type(mtpc_storage_fileUnknown),
queue = &i.value();
}
mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &to, int32 size, bool todata) : prev(0), next(0),
priority(0), _paused(false), inQueue(false), complete(false),
_localStatus(LocalNotTried), skippedBytes(0), nextRequestOffset(0), lastComplete(false),
dc(dc), _locationType(type), volume(0), local(0), secret(0),
id(id), access(access), file(to), fname(to), fileIsOpen(false), duplicateInData(todata), size(size), type(mtpc_storage_fileUnknown), _localTaskId(0) {
mtpFileLoader::mtpFileLoader(int32 dc, const uint64 &id, const uint64 &access, LocationType type, const QString &to, int32 size, bool todata)
: prev(0)
, next(0)
, priority(0)
, _paused(false)
, inQueue(false)
, complete(false)
, _localStatus(LocalNotTried)
, skippedBytes(0)
, nextRequestOffset(0)
, lastComplete(false)
, dc(dc)
, _locationType(type)
, volume(0)
, local(0)
, secret(0)
, id(id)
, access(access)
, file(to)
, fname(to)
, fileIsOpen(false)
, duplicateInData(todata)
, size(size)
, type(mtpc_storage_fileUnknown)
, _localTaskId(0) {
LoaderQueues::iterator i = queues.find(MTP::dld[0] + dc);
if (i == queues.cend()) {
i = queues.insert(MTP::dld[0] + dc, mtpFileLoaderQueue());
@ -411,8 +448,30 @@ void mtpFileLoader::localLoaded(const StorageImageSaved &result, const QByteArra
loadNext();
}
bool mtpFileLoader::tryingLocal() const {
return (_localStatus == LocalLoading);
bool mtpFileLoader::localAvailable() const {
if (_localStatus == LocalLoading || _localStatus == LocalLoaded || _localStatus == LocalNeedsTry) {
return true;
}
if (_localStatus == LocalNotFound || _localStatus == LocalFailed) {
return false;
}
bool result = false;
if (_locationType == UnknownFileLocation) {
result = Local::willImageLoad(storageKey(dc, volume, local));
} else {
if (duplicateInData) {
MediaKey mkey = mediaKey(_locationType, dc, id);
if (_locationType == DocumentFileLocation) {
result = Local::willStickerImageLoad(mkey);
} else if (_locationType == AudioFileLocation) {
result = Local::willAudioLoad(mkey);
}
}
}
_localStatus = result ? LocalNeedsTry : LocalNotFound;
return result;
}
void mtpFileLoader::start(bool loadFirst, bool prior) {
@ -432,10 +491,10 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
if (prior) {
if (inQueue && priority == _priority) {
if (loadFirst) {
if (!prev) return started(loadFirst, prior);
if (!prev) return startLoading(loadFirst, prior);
before = queue->start;
} else {
if (!next || next->priority < _priority) return started(loadFirst, prior);
if (!next || next->priority < _priority) return startLoading(loadFirst, prior);
after = next;
while (after->next && after->next->priority == _priority) {
after = after->next;
@ -444,7 +503,7 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
} else {
priority = _priority;
if (loadFirst) {
if (inQueue && !prev) return started(loadFirst, prior);
if (inQueue && !prev) return startLoading(loadFirst, prior);
before = queue->start;
} else {
if (inQueue) {
@ -456,7 +515,7 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
before = before->prev;
}
} else {
return started(loadFirst, prior);
return startLoading(loadFirst, prior);
}
} else {
if (queue->start && queue->start->priority == _priority) {
@ -474,13 +533,13 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
}
} else {
if (loadFirst) {
if (inQueue && (!prev || prev->priority == _priority)) return started(loadFirst, prior);
if (inQueue && (!prev || prev->priority == _priority)) return startLoading(loadFirst, prior);
before = prev;
while (before->prev && before->prev->priority != _priority) {
before = before->prev;
}
} else {
if (inQueue && !next) return started(loadFirst, prior);
if (inQueue && !next) return startLoading(loadFirst, prior);
after = queue->end;
}
}
@ -513,7 +572,7 @@ void mtpFileLoader::start(bool loadFirst, bool prior) {
} else {
LOG(("Queue Error: _start && !before && !after"));
}
return started(loadFirst, prior);
return startLoading(loadFirst, prior);
}
void mtpFileLoader::cancel() {
@ -549,15 +608,7 @@ void mtpFileLoader::cancelRequests() {
}
}
bool mtpFileLoader::loading() const {
return inQueue;
}
bool mtpFileLoader::paused() const {
return _paused;
}
void mtpFileLoader::started(bool loadFirst, bool prior) {
void mtpFileLoader::startLoading(bool loadFirst, bool prior) {
if ((queue->queries >= MaxFileQueries && (!loadFirst || !prior)) || complete) return;
loadPart();
}

View File

@ -100,6 +100,7 @@ struct StorageImageSaved {
enum LocalLoadStatus {
LocalNotTried,
LocalNeedsTry,
LocalNotFound,
LocalLoading,
LocalLoaded,
@ -139,9 +140,24 @@ public:
void pause();
void start(bool loadFirst = false, bool prior = true);
void cancel();
bool loading() const;
bool paused() const;
bool tryingLocal() const;
bool loading() const {
return inQueue;
}
bool paused() const {
return _paused;
}
bool started() const {
return inQueue || _paused;
}
bool loadingLocal() const {
return (_localStatus == LocalLoading);
}
bool localAvailable() const;
uint64 objId() const;
@ -161,7 +177,7 @@ private:
mtpFileLoaderQueue *queue;
bool _paused, inQueue, complete;
LocalLoadStatus _localStatus;
mutable LocalLoadStatus _localStatus;
bool tryLoadLocal();
void cancelRequests();
@ -172,7 +188,7 @@ private:
int32 nextRequestOffset;
bool lastComplete;
void started(bool loadFirst, bool prior);
void startLoading(bool loadFirst, bool prior);
void removeFromQueue();
void loadNext();

View File

@ -1271,7 +1271,7 @@ void OverviewInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
if (lnkPhoto) {
_menu->addAction(lang(lng_context_open_image), this, SLOT(openContextUrl()))->setEnabled(true);
} else {
if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loader) || (lnkDocument && lnkDocument->document()->loader)) {
if ((lnkVideo && lnkVideo->video()->loader) || (lnkAudio && lnkAudio->audio()->loadingStarted()) || (lnkDocument && lnkDocument->document()->loadingStarted())) {
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
} else {
if ((lnkVideo && !lnkVideo->video()->already(true).isEmpty()) || (lnkAudio && !lnkAudio->audio()->already(true).isEmpty()) || (lnkDocument && !lnkDocument->document()->already(true).isEmpty())) {
@ -1526,12 +1526,15 @@ void OverviewInner::saveContextFile() {
}
void OverviewInner::openContextFile() {
HistoryItem *was = App::hoveredLinkItem();
App::hoveredLinkItem(App::contextItem());
VideoLink *lnkVideo = dynamic_cast<VideoLink*>(_contextMenuLnk.data());
AudioLink *lnkAudio = dynamic_cast<AudioLink*>(_contextMenuLnk.data());
DocumentLink *lnkDocument = dynamic_cast<DocumentLink*>(_contextMenuLnk.data());
if (lnkVideo) VideoOpenLink(lnkVideo->video()).onClick(Qt::LeftButton);
if (lnkAudio) AudioOpenLink(lnkAudio->audio()).onClick(Qt::LeftButton);
if (lnkDocument) DocumentOpenLink(lnkDocument->document()).onClick(Qt::LeftButton);
App::hoveredLinkItem(was);
}
bool OverviewInner::onSearchMessages(bool searchCache) {

View File

@ -775,6 +775,13 @@ void AudioOpenLink::onClick(Qt::MouseButton button) const {
if (data->status != FileReady) return;
if (data->loader && !data->loader->started()) {
data->openOnSave = 1;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(QString());
return;
}
bool mp3 = (data->mime == qstr("audio/mp3"));
QString filename = saveFileName(lang(lng_save_audio), mp3 ? qsl("MP3 Audio (*.mp3);;All files (*.*)") : qsl("OGG Opus Audio (*.ogg);;All files (*.*)"), qsl("audio"), mp3 ? qsl(".mp3") : qsl(".ogg"), false);
if (!filename.isEmpty()) {
@ -885,10 +892,11 @@ const FileLocation &AudioData::location(bool check) {
void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) {
if (!data->date) return;
bool play = data->song() && App::hoveredLinkItem() && audioPlayer();
bool playMusic = data->song() && audioPlayer() && App::hoveredLinkItem();
bool playAnimation = data->isAnimation() && App::hoveredLinkItem() && App::hoveredLinkItem()->getMedia();
const FileLocation &location(data->location(true));
if (!location.isEmpty() || (!data->data.isEmpty() && play)) {
if (play) {
if (!location.isEmpty() || (!data->data.isEmpty() && (playMusic || playAnimation))) {
if (playMusic) {
SongMsgId playing;
AudioPlayerState playingState = AudioPlayerStopped;
audioPlayer()->currentState(&playing, &playingState);
@ -899,13 +907,23 @@ void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) {
audioPlayer()->play(song);
if (App::main()) App::main()->documentPlayProgress(song);
}
} else if (data->size < MediaViewImageSizeLimit && location.accessEnable()) {
if ((App::hoveredLinkItem() || App::contextItem()) && (data->isAnimation() || QImageReader(location.name()).canRead())) {
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());
} else if (data->size < MediaViewImageSizeLimit) {
if (!data->data.isEmpty() && playAnimation) {
if (openOnSave > 1) {
App::hoveredLinkItem()->getMedia()->playInline(App::hoveredLinkItem());
} else {
App::wnd()->showDocument(data, App::hoveredLinkItem());
}
} else if (location.accessEnable()) {
if ((App::hoveredLinkItem() || App::contextItem()) && (data->isAnimation() || QImageReader(location.name()).canRead())) {
App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem());
} else {
psOpenFile(location.name());
}
location.accessDisable();
} else {
psOpenFile(location.name());
}
location.accessDisable();
} else {
psOpenFile(location.name());
}
@ -914,6 +932,13 @@ void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) {
if (data->status != FileReady) return;
if (data->loader && !data->loader->started()) {
data->openOnSave = openOnSave;
data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId());
data->save(QString());
return;
}
QString name = data->name, filter;
MimeType mimeType = mimeTypeForName(data->mime);
QStringList p = mimeType.globPatterns();

View File

@ -945,6 +945,9 @@ struct AudioData {
bool loaded(bool check = false) {
return !data.isEmpty() || !already(check).isEmpty();
}
bool loadingStarted() {
return loader && loader->started();
}
float64 progress() const {
return loader ? loader->currentProgress() : ((status == FileDownloadFailed || (_location.name().isEmpty() && data.isEmpty())) ? 0 : 1);
@ -1141,6 +1144,9 @@ struct DocumentData {
bool loaded(bool check = false) {
return !data.isEmpty() || !already(check).isEmpty();
}
bool loadingStarted() {
return loader && loader->started();
}
void prepareAutoLoader();
StickerData *sticker() {
return (type == StickerDocument) ? static_cast<StickerData*>(_additional) : 0;

View File

@ -777,21 +777,21 @@ void Window::showPhoto(const PhotoLink *lnk, HistoryItem *item) {
}
void Window::showPhoto(PhotoData *photo, HistoryItem *item) {
Ui::hideLayer(true);
if (_mediaView->isHidden()) Ui::hideLayer(true);
_mediaView->showPhoto(photo, item);
_mediaView->activateWindow();
_mediaView->setFocus();
}
void Window::showPhoto(PhotoData *photo, PeerData *peer) {
Ui::hideLayer(true);
if (_mediaView->isHidden()) Ui::hideLayer(true);
_mediaView->showPhoto(photo, peer);
_mediaView->activateWindow();
_mediaView->setFocus();
}
void Window::showDocument(DocumentData *doc, HistoryItem *item) {
Ui::hideLayer(true);
if (_mediaView->isHidden()) Ui::hideLayer(true);
_mediaView->showDocument(doc, item);
_mediaView->activateWindow();
_mediaView->setFocus();