From b94533fcb2207b34aa578efcc7e1575990edd04c Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 23 Dec 2015 22:23:14 +0300 Subject: [PATCH] gif autoplay improved --- Telegram/SourceFiles/boxes/stickersetbox.cpp | 1 + Telegram/SourceFiles/dropdown.cpp | 2 + Telegram/SourceFiles/history.cpp | 112 ++++++------- Telegram/SourceFiles/historywidget.cpp | 7 +- Telegram/SourceFiles/layerwidget.cpp | 1 + Telegram/SourceFiles/layout.cpp | 97 ++++++----- Telegram/SourceFiles/layout.h | 4 +- Telegram/SourceFiles/localstorage.cpp | 18 ++- Telegram/SourceFiles/localstorage.h | 3 + Telegram/SourceFiles/mainwidget.cpp | 41 +++-- Telegram/SourceFiles/mediaview.cpp | 151 +++++++++++------- Telegram/SourceFiles/mediaview.h | 1 + .../SourceFiles/mtproto/mtpFileLoader.cpp | 107 +++++++++---- Telegram/SourceFiles/mtproto/mtpFileLoader.h | 26 ++- Telegram/SourceFiles/overviewwidget.cpp | 5 +- Telegram/SourceFiles/structs.cpp | 39 ++++- Telegram/SourceFiles/structs.h | 6 + Telegram/SourceFiles/window.cpp | 6 +- 18 files changed, 401 insertions(+), 226 deletions(-) diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp index 2b0182b05..f8ea8d119 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.cpp +++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp @@ -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)) { diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 49d6b8731..6a22b5a0f 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -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)) { diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index b078b2130..26e28337d 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -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()); } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index cbf8b4cdc..17ad05f62 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -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(_contextMenuLnk.data()); + HistoryItem *was = App::hoveredLinkItem(); + App::hoveredLinkItem(App::contextItem()); + VideoLink *lnkVideo = dynamic_cast(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_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() { diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 8287ec48e..73baaabe1 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -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)) { diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp index cebbcf2dc..e9c86a429 100644 --- a/Telegram/SourceFiles/layout.cpp +++ b/Telegram/SourceFiles/layout.cpp @@ -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; } diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h index d4cebb35a..c2e79e66c 100644 --- a/Telegram/SourceFiles/layout.h +++ b/Telegram/SourceFiles/layout.h @@ -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; diff --git a/Telegram/SourceFiles/localstorage.cpp b/Telegram/SourceFiles/localstorage.cpp index 418f1cfb1..79158f11d 100644 --- a/Telegram/SourceFiles/localstorage.cpp +++ b/Telegram/SourceFiles/localstorage.cpp @@ -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(); } diff --git a/Telegram/SourceFiles/localstorage.h b/Telegram/SourceFiles/localstorage.h index c653bf85f..6e946f055 100644 --- a/Telegram/SourceFiles/localstorage.h +++ b/Telegram/SourceFiles/localstorage.h @@ -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(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index f3e9f455d..baca09cd1 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -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()); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 61bc89983..9c5499f02 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -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(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(media)->photo()->full->load(); break; - case MediaTypeDocument: - case MediaTypeGif: static_cast(media)->getDocument()->thumb->load(); break; - case MediaTypeSticker: static_cast(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(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(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) { diff --git a/Telegram/SourceFiles/mediaview.h b/Telegram/SourceFiles/mediaview.h index d116397d5..5068d1bf3 100644 --- a/Telegram/SourceFiles/mediaview.h +++ b/Telegram/SourceFiles/mediaview.h @@ -146,6 +146,7 @@ private: bool fileShown() const; bool gifShown() const; + void stopGif(); style::sprite _docIcon; style::color _docIconColor; diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp index 81b81daf5..32aac4dcb 100644 --- a/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp +++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.cpp @@ -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(); } diff --git a/Telegram/SourceFiles/mtproto/mtpFileLoader.h b/Telegram/SourceFiles/mtproto/mtpFileLoader.h index aee364c54..23a005b02 100644 --- a/Telegram/SourceFiles/mtproto/mtpFileLoader.h +++ b/Telegram/SourceFiles/mtproto/mtpFileLoader.h @@ -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(); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 006abd3f1..fbdbb6185 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -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(_contextMenuLnk.data()); AudioLink *lnkAudio = dynamic_cast(_contextMenuLnk.data()); DocumentLink *lnkDocument = dynamic_cast(_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) { diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 7709719ec..95130ec3a 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -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(); diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index ac19e4a29..618496865 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -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(_additional) : 0; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 502df8e9b..d30e8bc3b 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -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();