diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index aa1b475e5..897bcd56f 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -48,6 +48,19 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org "lng_month11" = "November"; "lng_month12" = "December"; +"lng_month1_small" = "Jan"; +"lng_month2_small" = "Feb"; +"lng_month3_small" = "Mar"; +"lng_month4_small" = "Apr"; +"lng_month5_small" = "May"; +"lng_month6_small" = "Jun"; +"lng_month7_small" = "Jul"; +"lng_month8_small" = "Aug"; +"lng_month9_small" = "Sep"; +"lng_month10_small" = "Oct"; +"lng_month11_small" = "Nov"; +"lng_month12_small" = "Dec"; + "lng_weekday1" = "Mon"; "lng_weekday2" = "Tue"; "lng_weekday3" = "Wed"; diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index df83c214e..5931668df 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -1184,6 +1184,11 @@ mediaUnreadSize: 7px; mediaUnreadSkip: 5px; mediaUnreadTop: 6px; +msgFileRedColor: #e47272; +msgFileYellowColor: #efc274; +msgFileGreenColor: #61b96e; +msgFileBlueColor: #72b1df; + msgFileMenuSize: size(36px, 36px); msgFileSize: 44px; msgFilePadding: margins(14px, 12px, 11px, 12px); @@ -1231,8 +1236,16 @@ msgFileOutPlaySelected: sprite(180px, 146px, 20px, 18px); msgFileInPlay: sprite(160px, 164px, 20px, 18px); msgFileInPlaySelected: sprite(180px, 164px, 20px, 18px); +msgFileRed: sprite(0px, 425px, 20px, 20px); +msgFileYellow: sprite(20px, 425px, 20px, 20px); +msgFileGreen: sprite(40px, 425px, 20px, 20px); +msgFileBlue: sprite(60px, 425px, 20px, 20px); + msgFileOverDuration: 200; -msgFileRadialLine: 4px; +msgFileRadialLine: 3px; + +msgFileExtPadding: 8px; +msgFileExtTop: 30px; msgVideoSize: size(320px, 240px); @@ -2086,14 +2099,12 @@ mvDocExtFont: font(semibold 18px); mvDocExtColor: white; mvDocExtPadding: 10px; mvDocLinksTop: 57px; -mvDocRed: sprite(0px, 400px, 80px, 80px); -mvDocRedColor: #e47272; -mvDocYellow: sprite(80px, 400px, 80px, 80px); -mvDocYellowColor: #efc274; -mvDocGreen: sprite(160px, 400px, 80px, 80px); -mvDocGreenColor: #61b96e; -mvDocBlue: sprite(240px, 400px, 80px, 80px); -mvDocBlueColor: #72b1df; +mvDocRed: sprite(0px, 400px, 25px, 25px); +mvDocYellow: sprite(25px, 400px, 25px, 25px); +mvDocGreen: sprite(50px, 400px, 25px, 25px); +mvDocBlue: sprite(75px, 400px, 25px, 25px); +mvDocIconSize: 80px; + mvDocLink: linkButton(btnDefLink) { color: #4595d3; overColor: #4595d3; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index d814189e9..05f1cffe7 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -2137,10 +2137,10 @@ namespace App { prepareCorners(BotKeyboardDownCorners, st::msgRadius, st::botKbDownBg); prepareCorners(PhotoSelectOverlayCorners, st::msgRadius, st::overviewPhotoSelectOverlay); - prepareCorners(DocRedCorners, st::msgRadius, st::mvDocRedColor); - prepareCorners(DocYellowCorners, st::msgRadius, st::mvDocYellowColor); - prepareCorners(DocGreenCorners, st::msgRadius, st::mvDocGreenColor); - prepareCorners(DocBlueCorners, st::msgRadius, st::mvDocBlueColor); + prepareCorners(DocBlueCorners, st::msgRadius, st::msgFileBlueColor); + prepareCorners(DocGreenCorners, st::msgRadius, st::msgFileGreenColor); + prepareCorners(DocRedCorners, st::msgRadius, st::msgFileRedColor); + prepareCorners(DocYellowCorners, st::msgRadius, st::msgFileYellowColor); prepareCorners(MessageInCorners, st::msgRadius, st::msgInBg, &st::msgInShadow); prepareCorners(MessageInSelectedCorners, st::msgRadius, st::msgInBgSelected, &st::msgInShadowSelected); diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index 0582a6b88..4c0adfce5 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -49,39 +49,6 @@ struct ReplyMarkup { int32 flags; }; -enum RoundCorners { - NoneCorners = 0x00, // for images - BlackCorners, - ServiceCorners, - ServiceSelectedCorners, - SelectedOverlayCorners, - DateCorners, - DateSelectedCorners, - ForwardCorners, - MediaviewSaveCorners, - EmojiHoverCorners, - StickerHoverCorners, - BotKeyboardCorners, - BotKeyboardOverCorners, - BotKeyboardDownCorners, - PhotoSelectOverlayCorners, - - DocRedCorners, - DocYellowCorners, - DocGreenCorners, - DocBlueCorners, - - InShadowCorners, // for photos without bg - InSelectedShadowCorners, - - MessageInCorners, // with shadow - MessageInSelectedCorners, - MessageOutCorners, - MessageOutSelectedCorners, - - RoundCornersCount -}; - class LayeredWidget; namespace App { diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index f3133aaa3..79a869454 100644 Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index 39fc0ab8c..a0a3d4511 100644 Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ diff --git a/Telegram/SourceFiles/boxes/stickersetbox.cpp b/Telegram/SourceFiles/boxes/stickersetbox.cpp index 2ca8888c0..2b0182b05 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.cpp +++ b/Telegram/SourceFiles/boxes/stickersetbox.cpp @@ -699,7 +699,7 @@ StickersBox::StickersBox() : ItemListBox(st::boxScroll) , _topShadow(this, st::contactsAboutShadow) , _bottomShadow(this) , _scrollDelta(0) -, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPhotoSize - st::contactsPadding.left() - st::contactsPadding.right()) +, _aboutWidth(st::boxWideWidth - st::contactsPadding.left() - st::contactsPadding.left()) , _about(st::boxTextFont, lang(lng_stickers_reorder), _defaultOptions, _aboutWidth) , _aboutHeight(st::stickersReorderPadding.top() + _about.countHeight(_aboutWidth) + st::stickersReorderPadding.bottom()) { ItemListBox::init(&_inner, st::boxButtonPadding.top() + _save.height() + st::boxButtonPadding.bottom(), st::boxTitleHeight + _aboutHeight); @@ -778,7 +778,7 @@ void StickersBox::paintEvent(QPaintEvent *e) { p.fillRect(0, 0, width(), _aboutHeight, st::contactsAboutBg); p.setPen(st::stickersReorderFg); - _about.drawLeft(p, st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, width()); + _about.draw(p, st::contactsPadding.left(), st::stickersReorderPadding.top(), _aboutWidth, style::al_center); } void StickersBox::closePressed() { diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 488015252..533db8194 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -3320,12 +3320,6 @@ void HistoryPhoto::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x } } -void HistoryPhoto::getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const { - if (x >= 0 && y >= 0 && x < width && y < width) { - lnk = _openl; - } -} - void HistoryPhoto::updateFrom(const MTPMessageMedia &media, HistoryItem *parent, bool allowEmitResize) { if (media.type() == mtpc_messageMediaPhoto) { const MTPPhoto &photo(media.c_messageMediaPhoto().vphoto); @@ -3372,65 +3366,7 @@ ImagePtr HistoryPhoto::replyPreview() { return _data->makeReplyPreview(); } -QString formatSizeText(qint64 size) { - if (size >= 1024 * 1024) { // more than 1 mb - qint64 sizeTenthMb = (size * 10 / (1024 * 1024)); - return QString::number(sizeTenthMb / 10) + '.' + QString::number(sizeTenthMb % 10) + qsl(" MB"); - } - if (size >= 1024) { - qint64 sizeTenthKb = (size * 10 / 1024); - return QString::number(sizeTenthKb / 10) + '.' + QString::number(sizeTenthKb % 10) + qsl(" KB"); - } - return QString::number(size) + qsl(" B"); -} - -QString formatDownloadText(qint64 ready, qint64 total) { - QString readyStr, totalStr, mb; - if (total >= 1024 * 1024) { // more than 1 mb - qint64 readyTenthMb = (ready * 10 / (1024 * 1024)), totalTenthMb = (total * 10 / (1024 * 1024)); - readyStr = QString::number(readyTenthMb / 10) + '.' + QString::number(readyTenthMb % 10); - totalStr = QString::number(totalTenthMb / 10) + '.' + QString::number(totalTenthMb % 10); - mb = qsl("MB"); - } else if (total >= 1024) { - qint64 readyKb = (ready / 1024), totalKb = (total / 1024); - readyStr = QString::number(readyKb); - totalStr = QString::number(totalKb); - mb = qsl("KB"); - } else { - readyStr = QString::number(ready); - totalStr = QString::number(total); - mb = qsl("B"); - } - return lng_save_downloaded(lt_ready, readyStr, lt_total, totalStr, lt_mb, mb); -} - -QString formatDurationText(qint64 duration) { - qint64 hours = (duration / 3600), minutes = (duration % 3600) / 60, seconds = duration % 60; - return (hours ? QString::number(hours) + ':' : QString()) + (minutes >= 10 ? QString() : QString('0')) + QString::number(minutes) + ':' + (seconds >= 10 ? QString() : QString('0')) + QString::number(seconds); -} - -QString formatDurationAndSizeText(qint64 duration, qint64 size) { - return lng_duration_and_size(lt_duration, formatDurationText(duration), lt_size, formatSizeText(size)); -} - -QString formatGifAndSizeText(qint64 size) { - return lng_duration_and_size(lt_duration, qsl("GIF"), lt_size, formatSizeText(size)); -} - -QString formatPlayedText(qint64 played, qint64 duration) { - return lng_duration_played(lt_played, formatDurationText(played), lt_duration, formatDurationText(duration)); -} - namespace { - QString documentName(DocumentData *document) { - SongData *song = document->song(); - if (!song || (song->title.isEmpty() && song->performer.isEmpty())) return document->name; - - if (song->performer.isEmpty()) return song->title; - - return song->performer + QString::fromUtf8(" \xe2\x80\x93 ") + (song->title.isEmpty() ? qsl("Unknown Track") : song->title); - } - int32 videoMaxStatusWidth(VideoData *video) { int32 result = st::normalFont->width(formatDownloadText(video->size, video->size)); result = qMax(result, st::normalFont->width(formatDurationAndSizeText(video->duration, video->size))); @@ -3774,15 +3710,6 @@ void HistoryVideo::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x } } -void HistoryVideo::drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const { -} - -void HistoryVideo::getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const { - if (x >= 0 && y >= 0 && x < width && y < width) { - lnk = _data->already().isEmpty() ? (_data->loader ? _cancell : _savel) : _openl; - } -} - void HistoryVideo::setStatusSize(int32 newSize) const { HistoryFileMedia::setStatusSize(newSize, _data->size, _data->duration, 0); } @@ -3972,12 +3899,6 @@ void HistoryAudio::getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x } } -void HistoryAudio::drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const { -} - -void HistoryAudio::getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const { -} - const QString HistoryAudio::inDialogsText() const { return lang(lng_in_dlg_audio); } @@ -4045,11 +3966,9 @@ HistoryDocument::HistoryDocument(DocumentData *document) : HistoryFileMedia() , _data(document) , _linksavel(new DocumentSaveLink(_data)) , _linkcancell(new DocumentCancelLink(_data)) -, _name(documentName(_data)) { +, _name(documentName(_data)) +, _namew(st::semiboldFont->width(_name)) { setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data)); - - if (_name.isEmpty()) _name = qsl("Unknown File"); - _namew = st::semiboldFont->width(_name); setStatusSize(FileStatusSizeReady); @@ -4290,103 +4209,6 @@ void HistoryDocument::getState(TextLinkPtr &lnk, HistoryCursorState &state, int3 } } -void HistoryDocument::drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const { - if (width < st::msgPadding.left() + st::msgPadding.right() + 1) return; - - bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); - if (_data->loader) { - ensureAnimation(parent); - if (!_animation->radial.animating()) { - _animation->radial.start(_data->progress()); - } - } - bool showPause = updateStatusText(parent); - bool radial = isRadialAnimation(ms); - - int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; - bool wthumb = withThumb(); - - nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right(); - nametop = st::msgFileThumbNameTop; - nameright = st::msgFileThumbPadding.left(); - statustop = st::msgFileThumbStatusTop; - linktop = st::msgFileThumbLinkTop; - - QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width)); - 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); - p.drawPixmap(rthumb.topLeft(), thumb); - } else { - App::roundRect(p, rthumb, st::black, BlackCorners); - } - } else { - } - if (selected) { - App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); - } - - if (!radial && (already || hasdata)) { - } else { - 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)) { - p.setOpacity(st::msgDateImgBg->c.alphaF() * _animation->radial.opacity()); - p.setBrush(st::black); - } else if (_animation && _animation->_a_thumbOver.animating()) { - _animation->_a_thumbOver.step(ms); - float64 over = _animation->a_thumbOver.current(); - 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); - p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); - } - - p.setRenderHint(QPainter::HighQualityAntialiasing); - p.drawEllipse(inner); - p.setRenderHint(QPainter::HighQualityAntialiasing, false); - - style::sprite icon; - if (already || hasdata || _data->loader) { - icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); - } else { - icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); - } - p.setOpacity(radial ? _animation->radial.opacity() : 1); - p.drawSpriteCenter(inner, icon); - if (radial) { - p.setOpacity(1); - - QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine))); - _animation->radial.draw(p, rinner, selected ? st::msgInBgSelected : st::msgInBg); - } - } - - int32 namewidth = width - nameleft - nameright; - - p.setFont(st::semiboldFont); - p.setPen(st::black); - if (namewidth < _namew) { - p.drawTextLeft(nameleft, nametop, width, st::semiboldFont->elided(_name, namewidth)); - } else { - p.drawTextLeft(nameleft, nametop, width, _name, _namew); - } - - style::color status(selected ? st::mediaInFgSelected : st::mediaInFg); - p.setFont(st::normalFont); - p.setPen(status); - - p.drawTextLeft(nameleft, statustop, width, _statusText); - - p.drawTextLeft(nameleft, linktop, width, _link); -} - -void HistoryDocument::getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const { -} - const QString HistoryDocument::inDialogsText() const { return _name.isEmpty() ? lang(lng_in_dlg_file) : _name; } @@ -4474,7 +4296,7 @@ HistoryGif::HistoryGif(DocumentData *document) : HistoryFileMedia() , _thumbw(1) , _thumbh(1) , _gif(0) { - setLinks(new DocumentOpenLink(_data), new DocumentOpenLink(_data), new DocumentCancelLink(_data)); + setLinks(new GifOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data)); setStatusSize(FileStatusSizeReady); @@ -4486,7 +4308,7 @@ HistoryGif::HistoryGif(const HistoryGif &other) : HistoryFileMedia() , _thumbw(other._thumbw) , _thumbh(other._thumbh) , _gif(0) { - setLinks(new DocumentOpenLink(_data), new DocumentOpenLink(_data), new DocumentCancelLink(_data)); + setLinks(new GifOpenLink(_data), new GifOpenLink(_data), new DocumentCancelLink(_data)); setStatusSize(other._statusSize); } @@ -6136,7 +5958,7 @@ void HistoryMessage::initMedia(const MTPMessageMedia *media, QString ¤tTex void HistoryMessage::initMediaFromDocument(DocumentData *doc) { if (doc->sticker()) { _media = new HistorySticker(doc); - } else if (doc->type == AnimatedDocument || doc->mime.toLower() == qstr("image/gif")) { + } else if (doc->isAnimation()) { _media = new HistoryGif(doc); } else { _media = new HistoryDocument(doc); @@ -7452,7 +7274,7 @@ HistoryServiceMsg::~HistoryServiceMsg() { } HistoryDateMsg::HistoryDateMsg(History *history, HistoryBlock *block, const QDate &date) : -HistoryServiceMsg(history, block, clientMsgId(), QDateTime(date), langDayOfMonth(date)) { +HistoryServiceMsg(history, block, clientMsgId(), QDateTime(date), langDayOfMonthFull(date)) { } HistoryItem *createDayServiceMsg(History *history, HistoryBlock *block, QDateTime date) { diff --git a/Telegram/SourceFiles/history.h b/Telegram/SourceFiles/history.h index e979289b1..e58f02cc6 100644 --- a/Telegram/SourceFiles/history.h +++ b/Telegram/SourceFiles/history.h @@ -1077,6 +1077,8 @@ class MessageLink : public ITextLink { public: MessageLink(PeerId peer, MsgId msgid) : _peer(peer), _msgid(msgid) { } + MessageLink(HistoryItem *item) : _peer(item->history()->peer->id), _msgid(item->id) { + } void onClick(Qt::MouseButton button) const; PeerId peer() const { return _peer; @@ -1164,11 +1166,6 @@ public: virtual void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const = 0; virtual void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const = 0; - virtual void drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const { - } - virtual void getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const { - } - virtual void linkOver(HistoryItem *parent, const TextLinkPtr &lnk) { } virtual void linkOut(HistoryItem *parent, const TextLinkPtr &lnk) { @@ -1257,8 +1254,6 @@ public: void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const; - void getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const; - const QString inDialogsText() const; const QString inHistoryText() const; @@ -1303,17 +1298,6 @@ private: }; -static const int32 FileStatusSizeReady = 0x7FFFFFF0; -static const int32 FileStatusSizeLoaded = 0x7FFFFFF1; -static const int32 FileStatusSizeFailed = 0x7FFFFFF2; - -QString formatSizeText(qint64 size); -QString formatDownloadText(qint64 ready, qint64 total); -QString formatDurationText(qint64 duration); -QString formatDurationAndSizeText(qint64 duration, qint64 size); -QString formatGifAndSizeText(qint64 size); -QString formatPlayedText(qint64 played, qint64 duration); - class HistoryFileMedia : public HistoryMedia { public: @@ -1393,9 +1377,6 @@ public: void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const; - void drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; - void getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const; - const QString inDialogsText() const; const QString inHistoryText() const; @@ -1467,9 +1448,6 @@ public: void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const; - void drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; - void getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const; - const QString inDialogsText() const; const QString inHistoryText() const; @@ -1533,9 +1511,6 @@ public: void draw(Painter &p, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; void getState(TextLinkPtr &lnk, HistoryCursorState &state, int32 x, int32 y, const HistoryItem *parent) const; - void drawOverview(Painter &p, int32 width, const HistoryItem *parent, const QRect &r, bool selected, uint64 ms) const; - void getStateOverview(TextLinkPtr &lnk, int32 x, int32 y, const HistoryItem *parent, int32 width) const; - const QString inDialogsText() const; const QString inHistoryText() const; @@ -1591,8 +1566,8 @@ private: DocumentData *_data; TextLinkPtr _linksavel, _linkcancell; - int32 _namew; QString _name; + int32 _namew; int32 _thumbw; mutable int32 _linkw; diff --git a/Telegram/SourceFiles/lang.h b/Telegram/SourceFiles/lang.h index 508fcdb23..19a0648f2 100644 --- a/Telegram/SourceFiles/lang.h +++ b/Telegram/SourceFiles/lang.h @@ -81,6 +81,17 @@ LangString langCounted(ushort key0, ushort tag, float64 value); const char *langKeyName(LangKey key); inline LangString langDayOfMonth(const QDate &date) { + QDate c(QDate::currentDate()); + int32 month = date.month(), day = date.day(), year = date.year(), cyear = c.year(), cmonth = c.month(); + if (year != cyear) { + if (year > cyear + 1 || cyear > year + 1 || (year == cyear + 1 && month + 12 > cmonth + 3) || (cyear == year + 1 && cmonth + 12 > month + 3)) { + return (month > 0 && month <= 12) ? lng_month_day_year(lt_month, lang(LangKey(lng_month1_small + month - 1)), lt_day, QString::number(day), lt_year, QString::number(year)) : qsl("MONTH_ERR"); + } + } + return (month > 0 && month <= 12) ? lng_month_day(lt_month, lang(LangKey(lng_month1_small + month - 1)), lt_day, QString::number(day)) : qsl("MONTH_ERR"); +} + +inline LangString langDayOfMonthFull(const QDate &date) { QDate c(QDate::currentDate()); int32 month = date.month(), day = date.day(), year = date.year(), cyear = c.year(), cmonth = c.month(); if (year != cyear) { @@ -101,6 +112,14 @@ inline LangString langDayOfWeekFull(const QDate &date) { return (day > 0 && day <= 7) ? lang(LangKey(lng_weekday1_full + day - 1)) : qsl("DAY_ERR"); } +inline LangString langDateTime(const QDateTime &date) { + return lng_mediaview_date_time(lt_date, langDayOfMonth(date.date()), lt_time, date.time().toString(cTimeFormat())); +} + +inline LangString langDateTimeFull(const QDateTime &date) { + return lng_mediaview_date_time(lt_date, langDayOfMonthFull(date.date()), lt_time, date.time().toString(cTimeFormat())); +} + class LangLoader { public: const QString &errors() const; diff --git a/Telegram/SourceFiles/layout.cpp b/Telegram/SourceFiles/layout.cpp index 2a5b0c6ee..e5c93fffc 100644 --- a/Telegram/SourceFiles/layout.cpp +++ b/Telegram/SourceFiles/layout.cpp @@ -85,6 +85,123 @@ const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f) { return _historyTextNoMonoOptions; } +QString formatSizeText(qint64 size) { + if (size >= 1024 * 1024) { // more than 1 mb + qint64 sizeTenthMb = (size * 10 / (1024 * 1024)); + return QString::number(sizeTenthMb / 10) + '.' + QString::number(sizeTenthMb % 10) + qsl(" MB"); + } + if (size >= 1024) { + qint64 sizeTenthKb = (size * 10 / 1024); + return QString::number(sizeTenthKb / 10) + '.' + QString::number(sizeTenthKb % 10) + qsl(" KB"); + } + return QString::number(size) + qsl(" B"); +} + +QString formatDownloadText(qint64 ready, qint64 total) { + QString readyStr, totalStr, mb; + if (total >= 1024 * 1024) { // more than 1 mb + qint64 readyTenthMb = (ready * 10 / (1024 * 1024)), totalTenthMb = (total * 10 / (1024 * 1024)); + readyStr = QString::number(readyTenthMb / 10) + '.' + QString::number(readyTenthMb % 10); + totalStr = QString::number(totalTenthMb / 10) + '.' + QString::number(totalTenthMb % 10); + mb = qsl("MB"); + } else if (total >= 1024) { + qint64 readyKb = (ready / 1024), totalKb = (total / 1024); + readyStr = QString::number(readyKb); + totalStr = QString::number(totalKb); + mb = qsl("KB"); + } else { + readyStr = QString::number(ready); + totalStr = QString::number(total); + mb = qsl("B"); + } + return lng_save_downloaded(lt_ready, readyStr, lt_total, totalStr, lt_mb, mb); +} + +QString formatDurationText(qint64 duration) { + qint64 hours = (duration / 3600), minutes = (duration % 3600) / 60, seconds = duration % 60; + return (hours ? QString::number(hours) + ':' : QString()) + (minutes >= 10 ? QString() : QString('0')) + QString::number(minutes) + ':' + (seconds >= 10 ? QString() : QString('0')) + QString::number(seconds); +} + +QString formatDurationAndSizeText(qint64 duration, qint64 size) { + return lng_duration_and_size(lt_duration, formatDurationText(duration), lt_size, formatSizeText(size)); +} + +QString formatGifAndSizeText(qint64 size) { + return lng_duration_and_size(lt_duration, qsl("GIF"), lt_size, formatSizeText(size)); +} + +QString formatPlayedText(qint64 played, qint64 duration) { + return lng_duration_played(lt_played, formatDurationText(played), lt_duration, formatDurationText(duration)); +} + +QString documentName(DocumentData *document) { + SongData *song = document->song(); + if (!song || (song->title.isEmpty() && song->performer.isEmpty())) { + return document->name.isEmpty() ? qsl("Unknown File") : document->name; + } + + if (song->performer.isEmpty()) return song->title; + + return song->performer + QString::fromUtf8(" \xe2\x80\x93 ") + (song->title.isEmpty() ? qsl("Unknown Track") : song->title); +} + +int32 documentColorIndex(DocumentData *document, QString &ext) { + int32 colorIndex = 0; + + QString name = document ? (document->name.isEmpty() ? (document->sticker() ? lang(lng_in_dlg_sticker) : qsl("Unknown File")) : document->name) : lang(lng_message_empty); + name = name.toLower(); + int32 lastDot = name.lastIndexOf('.'); + QString mime = document ? document->mime.toLower() : QString(); + if (name.endsWith(qstr(".doc")) || + name.endsWith(qstr(".txt")) || + name.endsWith(qstr(".psd")) || + mime.startsWith(qstr("text/")) + ) { + colorIndex = 0; + } else if ( + name.endsWith(qstr(".xls")) || + name.endsWith(qstr(".csv")) + ) { + colorIndex = 1; + } else if ( + name.endsWith(qstr(".pdf")) || + name.endsWith(qstr(".ppt")) || + name.endsWith(qstr(".key")) + ) { + colorIndex = 2; + } else if ( + name.endsWith(qstr(".zip")) || + name.endsWith(qstr(".rar")) || + name.endsWith(qstr(".ai")) || + name.endsWith(qstr(".mp3")) || + name.endsWith(qstr(".mov")) || + name.endsWith(qstr(".avi")) + ) { + colorIndex = 3; + } else { + QChar ch = (lastDot >= 0 && lastDot + 1 < name.size()) ? name.at(lastDot + 1) : (name.isEmpty() ? (mime.isEmpty() ? '0' : mime.at(0)) : name.at(0)); + colorIndex = (ch.unicode() % 4); + } + + ext = document ? ((lastDot < 0 || lastDot + 2 > name.size()) ? name : name.mid(lastDot + 1)) : QString(); + + return colorIndex; +} + +style::color documentColor(int32 colorIndex) { + static style::color colors[] = { st::msgFileBlueColor, st::msgFileGreenColor, st::msgFileRedColor, st::msgFileYellowColor }; + return colors[colorIndex & 3]; +} + +style::sprite documentCorner(int32 colorIndex) { + static style::sprite corners[] = { st::msgFileBlue, st::msgFileGreen, st::msgFileRed, st::msgFileYellow }; + return corners[colorIndex & 3]; +} + +RoundCorners documentCorners(int32 colorIndex) { + return RoundCorners(DocBlueCorners + (colorIndex & 3)); +} + void LayoutRadialProgressItem::linkOver(const TextLinkPtr &lnk) { if (lnk == _savel || lnk == _cancell) { a_iconOver.start(1); @@ -168,7 +285,7 @@ void LayoutAbstractFileItem::setStatusSize(int32 newSize, int32 fullSize, int32 LayoutOverviewDate::LayoutOverviewDate(const QDate &date, int32 top) : _info(top) , _date(date) - , _text(langDayOfMonth(date)) { + , _text(langDayOfMonthFull(date)) { } void LayoutOverviewDate::initDimensions() { @@ -186,14 +303,233 @@ void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent, int32 top) : LayoutAbstractFileItem(parent) , _info(top) -, _data(document) { +, _data(document) +, _msgl(new MessageLink(parent)) +, _name(documentName(_data)) +, _date(langDateTime(date(_data->date))) +, _namew(st::semiboldFont->width(_name)) +, _datew(st::normalFont->width(_date)) +, _colorIndex(documentColorIndex(_data, _ext)) { + setLinks(new DocumentOpenLink(_data), new DocumentSaveLink(_data), new DocumentCancelLink(_data)); + + setStatusSize(FileStatusSizeReady, _data->size, _data->song() ? _data->song()->duration : -1, 0); + + if (withThumb()) { + _data->thumb->load(); + int32 tw = _data->thumb->width(), th = _data->thumb->height(); + if (tw > th) { + _thumbw = (tw * st::msgFileThumbSize) / th; + } else { + _thumbw = st::msgFileThumbSize; + } + } else { + _thumbw = 0; + } + + _extw = st::semiboldFont->width(_ext); + if (_extw > st::msgFileThumbSize - st::msgFileExtPadding * 2) { + _ext = st::semiboldFont->elided(_ext, st::msgFileThumbSize - st::msgFileExtPadding * 2, Qt::ElideMiddle); + _extw = st::semiboldFont->width(_ext); + } } void LayoutOverviewDocument::initDimensions() { _maxw = st::profileMaxWidth; - _minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom(); + _minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() + st::lineWidth; } void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const { + bool selected = (selection == FullSelection); + bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); + if (_data->loader) { + ensureRadial(); + if (!_radial->animating()) { + _radial->start(_data->progress()); + } + } + updateStatusText(); + bool radial = isRadialAnimation(ms); + int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; + bool wthumb = withThumb(); + + nameleft = st::msgFileThumbSize + st::msgFileThumbPadding.right(); + nametop = st::linksBorder + st::msgFileThumbNameTop; + statustop = st::linksBorder + st::msgFileThumbStatusTop; + linktop = st::linksBorder + st::msgFileThumbLinkTop; + + QRect shadow(rtlrect(nameleft, 0, _width - nameleft, st::linksBorder, _width)); + if (clip.intersects(shadow)) { + p.fillRect(clip.intersected(shadow), st::linksBorderColor); + } + + QRect rthumb(rtlrect(0, st::linksBorder + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, _width)); + 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); + 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)) { + style::sprite icon = documentCorner(_colorIndex); + p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - icon.pxWidth()), 0), icon); + if (!_ext.isEmpty()) { + p.setFont(st::semiboldFont); + p.setPen(st::white); + p.drawText(rthumb.left() + (rthumb.width() - _extw) / 2, rthumb.top() + st::msgFileExtTop + st::semiboldFont->ascent, _ext); + } + } + } + if (selected) { + App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, SelectedOverlayCorners); + p.drawSprite(rthumb.topLeft() + QPoint(rtl() ? 0 : (rthumb.width() - st::linksPhotoCheck.pxWidth()), rthumb.height() - st::linksPhotoCheck.pxHeight()), st::linksPhotoChecked); + } + + if (!radial && (already || hasdata)) { + } else { + 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)) { + p.setOpacity(st::msgDateImgBg->c.alphaF() * _radial->opacity()); + p.setBrush(st::black); + } else if (_a_iconOver.animating()) { + _a_iconOver.step(ms); + float64 over = a_iconOver.current(); + 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); + p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); + } + + p.setRenderHint(QPainter::HighQualityAntialiasing); + p.drawEllipse(inner); + p.setRenderHint(QPainter::HighQualityAntialiasing, false); + + style::sprite icon; + if (already || hasdata || _data->loader) { + icon = (selected ? st::msgFileInCancelSelected : st::msgFileInCancel); + } else { + icon = (selected ? st::msgFileInDownloadSelected : st::msgFileInDownload); + } + p.setOpacity(radial ? _radial->opacity() : 1); + p.drawSpriteCenter(inner, icon); + if (radial) { + p.setOpacity(1); + + QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine))); + _radial->draw(p, rinner, selected ? st::msgInBgSelected : st::msgInBg); + } + } + } + } + + int32 namewidth = _width - nameleft - nameright; + + if (clip.intersects(rtlrect(nameleft, nametop, qMin(namewidth, _namew), st::semiboldFont->height, _width))) { + p.setFont(st::semiboldFont); + p.setPen(st::black); + if (namewidth < _namew) { + p.drawTextLeft(nameleft, nametop, _width, st::semiboldFont->elided(_name, namewidth)); + } else { + p.drawTextLeft(nameleft, nametop, _width, _name, _namew); + } + } + + if (clip.intersects(QRect(0, statustop, _width, st::normalFont->height))) { + p.setFont(st::normalFont); + p.setPen(st::mediaInFg); + p.drawTextLeft(nameleft, statustop, _width, _statusText); + } + if (clip.intersects(rtlrect(nameleft, linktop, _datew, st::normalFont->height, _width))) { + p.setFont(textlnkDrawOver(_msgl) ? st::normalFont->underline() : st::normalFont); + p.setPen(st::mediaInFg); + p.drawTextLeft(nameleft, linktop, _width, _date, _datew); + } +} + +void LayoutOverviewDocument::getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const { + bool already = !_data->already().isEmpty(), hasdata = !_data->data.isEmpty(); + + updateStatusText(); + + int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0; + bool wthumb = withThumb(); + + nameleft = st::msgFileThumbSize + st::msgFileThumbPadding.right(); + nametop = st::linksBorder + st::msgFileThumbNameTop; + statustop = st::linksBorder + st::msgFileThumbStatusTop; + linktop = st::linksBorder + st::msgFileThumbLinkTop; + + 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 (_data->status != FileUploadFailed) { + if (rtlrect(nameleft, linktop, _datew, st::normalFont->height, _width).contains(x, y)) { + link = _msgl; + return; + } + } + if (!_data->loader && _data->access) { + if (rtlrect(0, st::linksBorder, nameleft, _height - st::linksBorder, _width).contains(x, y)) { + link = _openl; + return; + } + if (rtlrect(nameleft, nametop, qMin(_width - nameleft - nameright, _namew), st::semiboldFont->height, _width).contains(x, y)) { + link = _openl; + return; + } + } +} + +void LayoutOverviewDocument::updateStatusText() const { + bool showPause = false; + int32 statusSize = 0, realDuration = 0; + if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) { + statusSize = FileStatusSizeFailed; + } else if (_data->status == FileUploading) { + statusSize = _data->uploadOffset; + } else if (_data->loader) { + 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); + } + + 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 if (!_data->already().isEmpty() || !_data->data.isEmpty()) { + statusSize = FileStatusSizeLoaded; + } else { + statusSize = FileStatusSizeReady; + } + if (statusSize != _statusSize) { + setStatusSize(statusSize, _data->size, _data->song() ? _data->song()->duration : -1, realDuration); + } } diff --git a/Telegram/SourceFiles/layout.h b/Telegram/SourceFiles/layout.h index e1e20eb9f..f4409ad0f 100644 --- a/Telegram/SourceFiles/layout.h +++ b/Telegram/SourceFiles/layout.h @@ -28,6 +28,56 @@ extern TextParseOptions _historyTextOptions, _historyBotOptions, _historyTextNoM const TextParseOptions &itemTextOptions(History *h, PeerData *f); const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f); +enum RoundCorners { + NoneCorners = 0x00, // for images + BlackCorners, + ServiceCorners, + ServiceSelectedCorners, + SelectedOverlayCorners, + DateCorners, + DateSelectedCorners, + ForwardCorners, + MediaviewSaveCorners, + EmojiHoverCorners, + StickerHoverCorners, + BotKeyboardCorners, + BotKeyboardOverCorners, + BotKeyboardDownCorners, + PhotoSelectOverlayCorners, + + DocBlueCorners, + DocGreenCorners, + DocRedCorners, + DocYellowCorners, + + InShadowCorners, // for photos without bg + InSelectedShadowCorners, + + MessageInCorners, // with shadow + MessageInSelectedCorners, + MessageOutCorners, + MessageOutSelectedCorners, + + RoundCornersCount +}; + +static const int32 FileStatusSizeReady = 0x7FFFFFF0; +static const int32 FileStatusSizeLoaded = 0x7FFFFFF1; +static const int32 FileStatusSizeFailed = 0x7FFFFFF2; + +QString formatSizeText(qint64 size); +QString formatDownloadText(qint64 ready, qint64 total); +QString formatDurationText(qint64 duration); +QString formatDurationAndSizeText(qint64 duration, qint64 size); +QString formatGifAndSizeText(qint64 size); +QString formatPlayedText(qint64 played, qint64 duration); + +QString documentName(DocumentData *document); +int32 documentColorIndex(DocumentData *document, QString &ext); +style::color documentColor(int32 colorIndex); +style::sprite documentCorner(int32 colorIndex); +RoundCorners documentCorners(int32 colorIndex); + class LayoutMediaItem; class OverviewItemInfo; @@ -167,7 +217,7 @@ protected: mutable RadialAnimation *_radial; anim::fvalue a_iconOver; - Animation _a_iconOver; + mutable Animation _a_iconOver; private: LayoutRadialProgressItem(const LayoutRadialProgressItem &other); @@ -237,6 +287,7 @@ public: virtual void initDimensions(); virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const; + virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const; virtual DocumentData *getDocument() const { return _data; @@ -265,13 +316,15 @@ protected: private: OverviewItemInfo _info; DocumentData *_data; + TextLinkPtr _msgl; - QString _name, _date; - int32 _namew, _datew; - int32 _thumbw; + QString _name, _date, _ext; + int32 _namew, _datew, _extw; + int32 _thumbw, _colorIndex; bool withThumb() const { - return !_data->song() && !_data->thumb->isNull() && _data->thumb->width() && _data->thumb->height(); + return !_data->thumb->isNull() && _data->thumb->width() && _data->thumb->height(); } + void updateStatusText() const; }; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index d292c49ba..7853dec45 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1880,9 +1880,12 @@ void MainWidget::documentLoadProgress(mtpFileLoader *loader) { } else if (document->openOnSave > 0 && document->size < MediaViewImageSizeLimit) { const FileLocation &location(document->location(true)); if (location.accessEnable()) { - if (!item || !item->getMedia() || !item->getMedia()->playInline(item)) { - QImageReader reader(location.name()); - if (reader.canRead() && item) { + if (document->openOnSave > 1) { + if (!item || !item->getMedia() || !item->getMedia()->playInline(item)) { + psOpenFile(already); + } + } else { + if (item && (document->isAnimation() || QImageReader(location.name()).canRead())) { App::wnd()->showDocument(document, item); } else { psOpenFile(already); @@ -4509,7 +4512,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) { QDateTime datetime = date(d.vdate); QString name = App::self()->firstName; - QString day = langDayOfWeekFull(datetime.date()), date = langDayOfMonth(datetime.date()), time = datetime.time().toString(cTimeFormat()); + QString day = langDayOfWeekFull(datetime.date()), date = langDayOfMonthFull(datetime.date()), time = datetime.time().toString(cTimeFormat()); QString device = qs(d.vdevice), location = qs(d.vlocation); LangString text = lng_new_authorization(lt_name, App::self()->firstName, lt_day, day, lt_date, date, lt_time, time, lt_device, device, lt_location, location); App::wnd()->serviceNotification(text); diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index daec9dc77..95db2d03a 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -286,7 +286,7 @@ void MediaView::updateDocSize() { _docSize = formatSizeText(_doc->size); } _docSizeWidth = st::mvFont->width(_docSize); - int32 maxw = st::mvDocSize.width() - st::mvDocBlue.pxWidth() - st::mvDocPadding * 3; + int32 maxw = st::mvDocSize.width() - st::mvDocIconSize - st::mvDocPadding * 3; if (_docSizeWidth > maxw) { _docSize = st::mvFont->elided(_docSize, maxw); _docSizeWidth = st::mvFont->width(_docSize); @@ -298,21 +298,21 @@ void MediaView::updateControls() { if (_doc->loader) { _docDownload.hide(); _docSaveAs.hide(); - _docCancel.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocBlue.pxWidth(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); + _docCancel.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); _docCancel.show(); if (!_docRadialFirst) _docRadialFirst = _docRadialLast = _docRadialStart = getms(); if (!_a_state.animating()) _a_state.start(); _a_state.step(); } else { if (_doc->already(true).isEmpty()) { - _docDownload.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocBlue.pxWidth(), _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::mvDocBlue.pxWidth() + _docDownload.width(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); + _docSaveAs.moveToLeft(_docRect.x() + 2.5 * st::mvDocPadding + st::mvDocIconSize + _docDownload.width(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); _docSaveAs.show(); _docCancel.hide(); } else { _docDownload.hide(); - _docSaveAs.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocBlue.pxWidth(), _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); + _docSaveAs.moveToLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocLinksTop); _docSaveAs.show(); _docCancel.hide(); } @@ -940,44 +940,16 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty if (_current.isNull() && _currentGif.isNull()) { if (!_doc || _doc->thumb->isNull()) { + int32 colorIndex = documentColorIndex(_doc, _docExt); + _docIconColor = documentColor(colorIndex); style::sprite thumbs[] = { st::mvDocBlue, st::mvDocGreen, st::mvDocRed, st::mvDocYellow }; - style::color colors[] = { st::mvDocBlueColor, st::mvDocGreenColor, st::mvDocRedColor, st::mvDocYellowColor }; - QString name = _doc ? _doc->name.toLower() : QString(), mime = _doc ? _doc->mime.toLower() : QString(); - if (name.endsWith(qstr(".doc")) || - name.endsWith(qstr(".txt")) || - name.endsWith(qstr(".psd")) || - mime.startsWith(qstr("text/")) - ) { - _docIcon = thumbs[0]; - _docIconColor = colors[0]; - } else if ( - name.endsWith(qstr(".xls")) || - name.endsWith(qstr(".csv")) - ) { - _docIcon = thumbs[1]; - _docIconColor = colors[1]; - } else if ( - name.endsWith(qstr(".pdf")) || - name.endsWith(qstr(".ppt")) || - name.endsWith(qstr(".key")) - ) { - _docIcon = thumbs[2]; - _docIconColor = colors[2]; - } else if ( - name.endsWith(qstr(".zip")) || - name.endsWith(qstr(".rar")) || - name.endsWith(qstr(".ai")) || - name.endsWith(qstr(".mp3")) || - name.endsWith(qstr(".mov")) || - name.endsWith(qstr(".avi")) - ) { - _docIcon = thumbs[3]; - _docIconColor = colors[3]; - } else { - int ext = name.lastIndexOf('.'); - QChar ch = (ext >= 0 && ext + 1 < name.size()) ? name.at(ext + 1) : (name.isEmpty() ? (mime.isEmpty() ? '0' : mime.at(0)) : name.at(0)); - _docIcon = thumbs[ch.unicode() % 4]; - _docIconColor = colors[ch.unicode() % 4]; + _docIcon = thumbs[colorIndex]; + + int32 extmaxw = (st::mvDocIconSize - st::mvDocExtPadding * 2); + _docExtWidth = st::mvDocExtFont->width(_docExt); + if (_docExtWidth > extmaxw) { + _docExt = st::mvDocNameFont->elided(_docExt, extmaxw, Qt::ElideMiddle); + _docExtWidth = st::mvDocNameFont->width(_docExt); } } else { _doc->thumb->load(); @@ -985,35 +957,25 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty if (!tw || !th) { _docThumbx = _docThumby = _docThumbw = 0; } else if (tw > th) { - _docThumbw = (tw * st::mvDocBlue.pxHeight()) / th; - _docThumbx = (_docThumbw - st::mvDocBlue.pxWidth()) / 2; + _docThumbw = (tw * st::mvDocIconSize) / th; + _docThumbx = (_docThumbw - st::mvDocIconSize) / 2; _docThumby = 0; } else { - _docThumbw = st::mvDocBlue.pxWidth(); + _docThumbw = st::mvDocIconSize; _docThumbx = 0; - _docThumby = ((th * _docThumbw) / tw - st::mvDocBlue.pxHeight()) / 2; + _docThumby = ((th * _docThumbw) / tw - st::mvDocIconSize) / 2; } } - int32 maxw = st::mvDocSize.width() - st::mvDocBlue.pxWidth() - st::mvDocPadding * 3; + int32 maxw = st::mvDocSize.width() - st::mvDocIconSize - st::mvDocPadding * 3; _docName = (!_doc || _doc->name.isEmpty()) ? lang(_doc ? (_doc->type == StickerDocument ? lng_in_dlg_sticker : lng_mediaview_doc_image) : lng_message_empty) : _doc->name; - int32 lastDot = _docName.lastIndexOf('.'); - _docExt = _doc ? ((lastDot < 0 || lastDot + 2 > _docName.size()) ? _docName : _docName.mid(lastDot + 1)) : QString(); _docNameWidth = st::mvDocNameFont->width(_docName); if (_docNameWidth > maxw) { _docName = st::mvDocNameFont->elided(_docName, maxw, Qt::ElideMiddle); _docNameWidth = st::mvDocNameFont->width(_docName); } - int32 extmaxw = (st::mvDocBlue.pxWidth() - st::mvDocExtPadding * 2); - - _docExtWidth = st::mvDocExtFont->width(_docExt); - if (_docExtWidth > extmaxw) { - _docExt = st::mvDocNameFont->elided(_docExt, extmaxw, Qt::ElideMiddle); - _docExtWidth = st::mvDocNameFont->width(_docExt); - } - _docRadialFirst = _docRadialLast = _docRadialStart = 0; float64 prg = (_doc && _doc->loader) ? _doc->loader->currentProgress() : 0; @@ -1021,7 +983,7 @@ void MediaView::displayDocument(DocumentData *doc, HistoryItem *item) { // empty // _docSize is updated in updateControls() _docRect = QRect((width() - st::mvDocSize.width()) / 2, (height() - st::mvDocSize.height()) / 2, st::mvDocSize.width(), st::mvDocSize.height()); - _docIconRect = myrtlrect(_docRect.x() + st::mvDocPadding, _docRect.y() + st::mvDocPadding, st::mvDocBlue.pxWidth(), st::mvDocBlue.pxHeight()); + _docIconRect = myrtlrect(_docRect.x() + st::mvDocPadding, _docRect.y() + st::mvDocPadding, st::mvDocIconSize, st::mvDocIconSize); } else if (!_current.isNull()) { _current.setDevicePixelRatio(cRetinaFactor()); _w = _current.width() / cIntRetinaFactor(); @@ -1198,19 +1160,18 @@ void MediaView::paintEvent(QPaintEvent *e) { if (_docIconRect.intersects(r)) { icon = true; if (!_doc || _doc->thumb->isNull()) { + p.fillRect(_docIconRect, _docIconColor->b); if ((!_doc || !_doc->already().isEmpty()) && (!_docRadialStart || _docRadialOpacity < 1)) { - p.drawPixmap(_docIconRect.topLeft(), App::sprite(), _docIcon); + p.drawSprite(_docIconRect.topLeft() + QPoint(rtl() ? 0 : (_docIconRect.width() - _docIcon.pxWidth()), 0), _docIcon); p.setPen(st::mvDocExtColor->p); p.setFont(st::mvDocExtFont->f); if (!_docExt.isEmpty()) { p.drawText(_docIconRect.x() + (_docIconRect.width() - _docExtWidth) / 2, _docIconRect.y() + st::mvDocExtTop + st::mvDocExtFont->ascent, _docExt); } - } else { - p.fillRect(_docIconRect, _docIconColor->b); } } else { int32 rf(cIntRetinaFactor()); - p.drawPixmap(_docIconRect.topLeft(), _doc->thumb->pix(_docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mvDocBlue.pxWidth() * rf, st::mvDocBlue.pxHeight() * rf)); + p.drawPixmap(_docIconRect.topLeft(), _doc->thumb->pix(_docThumbw), QRect(_docThumbx * rf, _docThumby * rf, st::mvDocIconSize * rf, st::mvDocIconSize * rf)); } float64 o = overLevel(OverIcon); @@ -1251,11 +1212,11 @@ void MediaView::paintEvent(QPaintEvent *e) { name = true; p.setPen(st::mvDocNameColor->p); p.setFont(st::mvDocNameFont->f); - p.drawTextLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocBlue.pxWidth(), _docRect.y() + st::mvDocPadding + st::mvDocNameTop, width(), _docName, _docNameWidth); + p.drawTextLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocNameTop, width(), _docName, _docNameWidth); p.setPen(st::mvDocSizeColor->p); p.setFont(st::mvFont->f); - p.drawTextLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocBlue.pxWidth(), _docRect.y() + st::mvDocPadding + st::mvDocSizeTop, width(), _docSize, _docSizeWidth); + p.drawTextLeft(_docRect.x() + 2 * st::mvDocPadding + st::mvDocIconSize, _docRect.y() + st::mvDocPadding + st::mvDocSizeTop, width(), _docSize, _docSizeWidth); } } } diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index 9fe0ec077..df1ee6bb4 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -306,7 +306,18 @@ void OverviewInner::fixItemIndex(int32 ¤t, MsgId msgId) const { } } } - } else { + } else if (_type == OverviewDocuments) { + int32 l = _items.size(); + if (current < 0 || current >= l || complexMsgId(_items.at(current)->getItem()) != msgId) { + current = -1; + for (int32 i = 0; i < l; ++i) { + if (complexMsgId(_items.at(i)->getItem()) == msgId) { + current = i; + break; + } + } + } + } else if (_type == OverviewLinks) { int32 l = _cachedItems.size(); if (current < 0 || current >= l || _cachedItems[current].msgid != msgId) { current = -1; @@ -498,7 +509,17 @@ void OverviewInner::moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32 } else { msgId = (index >= indexskip) ? _history->overview[_type][index - indexskip] : (-_migrated->overview[_type][index]); } - } else { + } else if (_type == OverviewDocuments) { + while (index >= 0 && index < _items.size() && !_items.at(index)->toLayoutMediaItem()) { + index += (delta > 0) ? 1 : -1; + } + if (index < 0 || index >= _items.size()) { + msgId = 0; + index = -1; + } else { + msgId = complexMsgId(_items.at(index)->getItem()); + } + } else if (_type == OverviewLinks) { while (index >= 0 && index < _cachedItems.size() && !_cachedItems[index].msgid) { index += (delta > 0) ? 1 : -1; } @@ -897,7 +918,9 @@ void OverviewInner::addSelectionRange(int32 selFrom, int32 selTo, History *histo MsgId msgid = 0; if (_type == OverviewPhotos || _type == OverviewVideos || _type == OverviewAudioDocuments) { msgid = ((history == _history) ? 1 : -1) * history->overview[_type][i]; - } else { + } else if (_type == OverviewDocuments) { + msgid = complexMsgId(_items.at(i)->getItem()); + } else if (_type == OverviewLinks) { msgid = _cachedItems[i].msgid; } if (!msgid) continue; @@ -1001,28 +1024,29 @@ int32 OverviewInner::itemTop(const FullMsgId &msgId) const { void OverviewInner::preloadMore() { if (_inSearch) { if (!_searchRequest) { + MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument(); if (!_searchFull) { int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; - _searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchId ? SearchFromOffset : SearchFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchId ? SearchFromOffset : SearchFromStart)); + _searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchId ? SearchFromOffset : SearchFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchId ? SearchFromOffset : SearchFromStart)); if (!_lastSearchId) { _searchQueries.insert(_searchRequest, _searchQuery); } } else if (_migrated && !_searchFullMigrated) { int32 flags = (_migrated->peer->isChannel() && !_migrated->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; - _searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _migrated->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchMigratedId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart)); + _searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _migrated->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(_lastSearchMigratedId), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart), rpcFail(&OverviewInner::searchFailed, _lastSearchMigratedId ? SearchMigratedFromOffset : SearchMigratedFromStart)); } } } else if (App::main()) { if (_migrated && _history->overviewLoaded(_type)) { - App::main()->loadMediaBack(_migrated->peer, _type, _type != OverviewLinks); + App::main()->loadMediaBack(_migrated->peer, _type, false); } else { - App::main()->loadMediaBack(_history->peer, _type, _type != OverviewLinks); + App::main()->loadMediaBack(_history->peer, _type, false); } } } bool OverviewInner::preloadLocal() { - if (_type != OverviewLinks) return false; + if (_type != OverviewLinks && _type != OverviewDocuments) return false; if (_cachedItemsToBeLoaded >= migratedIndexSkip() + _history->overview[_type].size()) return false; _cachedItemsToBeLoaded += LinksOverviewPerPage; mediaOverviewUpdated(); @@ -1198,7 +1222,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) { if (m) { p.translate(pos.x(), pos.y()); - m->drawOverview(p, _vsize, item, r.translated(-pos.x(), -pos.y()), sel == FullSelection, ms); +// m->drawOverview(p, _vsize, item, r.translated(-pos.x(), -pos.y()), sel == FullSelection, ms); p.translate(-pos.x(), -pos.y()); } } @@ -1229,7 +1253,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) { } } - m->drawOverview(p, _rowWidth, item, r.translated(-_rowsLeft, -_addToY - index * _rowHeight), (sel == FullSelection), ms); +// m->drawOverview(p, _rowWidth, item, r.translated(-_rowsLeft, -_addToY - index * _rowHeight), (sel == FullSelection), ms); } p.translate(0, _rowHeight); } @@ -1260,10 +1284,10 @@ void OverviewInner::paintEvent(QPaintEvent *e) { } else { int32 index = lnk->letter.isEmpty() ? 0 : (lnk->letter.at(0).unicode() % 4); switch (index) { - case 0: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::mvDocRedColor, DocRedCorners); break; - case 1: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::mvDocYellowColor, DocYellowCorners); break; - case 2: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::mvDocGreenColor, DocGreenCorners); break; - case 3: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::mvDocBlueColor, DocBlueCorners); break; + case 0: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::msgFileRedColor, DocRedCorners); break; + case 1: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::msgFileYellowColor, DocYellowCorners); break; + case 2: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::msgFileGreenColor, DocGreenCorners); break; + case 3: App::roundRect(p, QRect(0, top, st::dlgPhotoSize, st::dlgPhotoSize), st::msgFileBlueColor, DocBlueCorners); break; } if (!lnk->letter.isEmpty()) { @@ -1315,7 +1339,7 @@ void OverviewInner::paintEvent(QPaintEvent *e) { } p.fillRect(left, _cachedItems[i].y - curY, _rowWidth - left, st::linksBorder, st::linksBorderColor->b); } else { - QString str = langDayOfMonth(_cachedItems[i].date); + QString str = langDayOfMonthFull(_cachedItems[i].date); p.setPen(st::linksDateColor->p); p.setFont(st::msgFont->f); @@ -1373,10 +1397,10 @@ void OverviewInner::paintEvent(QPaintEvent *e) { } } - m->drawOverview(p, _rowWidth, item, r.translated(-_rowsLeft, -_addToY - curY), (sel == FullSelection), ms); +// m->drawOverview(p, _rowWidth, item, r.translated(-_rowsLeft, -_addToY - curY), (sel == FullSelection), ms); } } else { - QString str = langDayOfMonth(_cachedItems[i].date); + QString str = langDayOfMonthFull(_cachedItems[i].date); p.setPen(st::linksDateColor->p); p.setFont(st::msgFont->f); @@ -1436,7 +1460,7 @@ void OverviewInner::onUpdateSelected() { if (m.y() >= _addToY + row * vsize + st::overviewPhotoSkip && m.y() < _addToY + (row + 1) * vsize + st::overviewPhotoSkip) { HistoryMedia *media = item->getMedia(true); if (media) { - media->getStateOverview(lnk, m.x() - inRow * w - st::overviewPhotoSkip, m.y() - _addToY - row * vsize - st::overviewPhotoSkip, item, _vsize); +// media->getStateOverview(lnk, m.x() - inRow * w - st::overviewPhotoSkip, m.y() - _addToY - row * vsize - st::overviewPhotoSkip, item, _vsize); } } } @@ -1465,7 +1489,7 @@ void OverviewInner::onUpdateSelected() { if (upon && m.x() >= _rowsLeft && m.x() < _rowsLeft + _rowWidth) { HistoryMedia *media = item->getMedia(true); if (media) { - media->getStateOverview(lnk, m.x() - _rowsLeft, m.y() - _addToY - i * _rowHeight, item, _rowWidth); +// media->getStateOverview(lnk, m.x() - _rowsLeft, m.y() - _addToY - i * _rowHeight, item, _rowWidth); newsel = (item->history() == _migrated) ? (-item->id) : item->id; } } @@ -1482,7 +1506,7 @@ void OverviewInner::onUpdateSelected() { int32 top = _addToY + _items.at(i)->getOverviewItemInfo()->top(); if (!_items.at(i)->toLayoutMediaItem()) { // day item int32 h = _items.at(i)->height(); - if (i > 0 && ((top + h / 2) >= m.y() || i == _cachedItems.size() - 1)) { + if (i > 0 && ((top + h / 2) >= m.y() || i == _items.size() - 1)) { --i; if (!_items.at(i)->toLayoutMediaItem()) break; // wtf top = _addToY + _items.at(i)->getOverviewItemInfo()->top(); @@ -1576,7 +1600,7 @@ void OverviewInner::onUpdateSelected() { index = i; HistoryMedia *media = item->getMedia(true); if (media) { - media->getStateOverview(lnk, m.x() - _rowsLeft, m.y() - y, item, _rowWidth); +// media->getStateOverview(lnk, m.x() - _rowsLeft, m.y() - y, item, _rowWidth); } } break; @@ -2039,6 +2063,10 @@ void OverviewInner::switchType(MediaOverviewType type) { _dragItemIndex = _mousedItemIndex = _dragSelFromIndex = _dragSelToIndex = -1; _dragItem = _mousedItem = _dragSelFrom = _dragSelTo = 0; _lnkOverIndex = _lnkDownIndex = 0; + for (int32 i = 0, l = _items.size(); i != l; ++i) { + delete _items.at(i); + } + _items.clear(); _cachedItems.clear(); _cached.clear(); _type = type; @@ -2178,7 +2206,8 @@ bool OverviewInner::onSearchMessages(bool searchCache) { _searchQuery = q; _searchFull = _searchFullMigrated = false; int32 flags = (_history->peer->isChannel() && !_history->peer->isMegagroup()) ? MTPmessages_Search::flag_important_only : 0; - _searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), MTP_inputMessagesFilterUrl(), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, SearchFromStart), rpcFail(&OverviewInner::searchFailed, SearchFromStart)); + MTPmessagesFilter filter = (_type == OverviewLinks) ? MTP_inputMessagesFilterUrl() : MTP_inputMessagesFilterDocument(); + _searchRequest = MTP::send(MTPmessages_Search(MTP_int(flags), _history->peer->input, MTP_string(_searchQuery), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(SearchPerPage)), rpcDone(&OverviewInner::searchReceived, SearchFromStart), rpcFail(&OverviewInner::searchFailed, SearchFromStart)); _searchQueries.insert(_searchRequest, _searchQuery); } return false; @@ -2416,7 +2445,7 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) { if (allGood) { if (_cachedItems.size() > in && _cachedItems.at(in).msgid == msgid) { prevDate = _cachedItems.at(in).date; - if (fromResize && _type == OverviewLinks) { + if (fromResize) { _cachedItems[in].y = y; y += _cachedItems[in].link->countHeight(_rowWidth); } else { @@ -2426,13 +2455,13 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) { continue; } if (_cachedItems.size() > in + 1 && !_cachedItems.at(in).msgid && _cachedItems.at(in + 1).msgid == msgid) { // day item - if (fromResize && _type == OverviewLinks) { + if (fromResize) { _cachedItems[in].y = y; y += st::msgFont->height + st::linksDateMargin * 2 + st::linksBorder; } ++in; prevDate = _cachedItems.at(in).date; - if (fromResize && _type == OverviewLinks) { + if (fromResize) { _cachedItems[in].y = y; y += _cachedItems[in].link->countHeight(_rowWidth); } else { @@ -2465,20 +2494,12 @@ void OverviewInner::mediaOverviewUpdated(bool fromResize) { if (_cachedItems.size() > in) { _cachedItems[in] = CachedItem(msgid, item->date.date(), y); - if (_type == OverviewLinks) { - _cachedItems[in].link = cachedLink(item); - y += _cachedItems[in].link->countHeight(_rowWidth); - } else { - y += _rowHeight; - } + _cachedItems[in].link = cachedLink(item); + y += _cachedItems[in].link->countHeight(_rowWidth); } else { _cachedItems.push_back(CachedItem(msgid, item->date.date(), y)); - if (_type == OverviewLinks) { - _cachedItems.back().link = cachedLink(item); - y += _cachedItems.back().link->countHeight(_rowWidth); - } else { - y += _rowHeight; - } + _cachedItems.back().link = cachedLink(item); + y += _cachedItems.back().link->countHeight(_rowWidth); } ++in; } diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index af2408a59..3d5dad92d 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -875,7 +875,7 @@ const FileLocation &AudioData::location(bool check) { return _location; } -void DocumentOpenLink::doOpen(DocumentData *data) { +void DocumentOpenLink::doOpen(DocumentData *data, int32 openOnSave) { if (!data->date) return; bool play = data->song() && App::hoveredLinkItem() && audioPlayer(); @@ -893,13 +893,10 @@ void DocumentOpenLink::doOpen(DocumentData *data) { if (App::main()) App::main()->documentPlayProgress(song); } } else if (data->size < MediaViewImageSizeLimit && location.accessEnable()) { - if (!App::hoveredLinkItem() || !App::hoveredLinkItem()->getMedia() || !App::hoveredLinkItem()->getMedia()->playInline(App::hoveredLinkItem())) { - QImageReader reader(location.name()); - if (reader.canRead() && (App::hoveredLinkItem() || App::contextItem())) { - App::wnd()->showDocument(data, App::hoveredLinkItem() ? App::hoveredLinkItem() : App::contextItem()); - } else { - psOpenFile(location.name()); - } + 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 { @@ -926,7 +923,7 @@ void DocumentOpenLink::doOpen(DocumentData *data) { QString filename = saveFileName(lang(lng_save_file), filter, qsl("doc"), name, false); if (!filename.isEmpty()) { - data->openOnSave = 1; + data->openOnSave = openOnSave; data->openOnSaveMsgId = App::hoveredLinkItem() ? App::hoveredLinkItem()->fullId() : (App::contextItem() ? App::contextItem()->fullId() : FullMsgId()); data->save(filename); } @@ -937,6 +934,32 @@ void DocumentOpenLink::onClick(Qt::MouseButton button) const { doOpen(document()); } +void GifOpenLink::doOpen(DocumentData *data) { + if (!data->date) return; + + const FileLocation &location(data->location(true)); + if (!location.isEmpty()) { + if (data->size < MediaViewImageSizeLimit && location.accessEnable()) { + if (!App::hoveredLinkItem() || !App::hoveredLinkItem()->getMedia() || !App::hoveredLinkItem()->getMedia()->playInline(App::hoveredLinkItem())) { + psOpenFile(location.name()); + } + location.accessDisable(); + } else { + psOpenFile(location.name()); + } + return; + } + + if (data->status != FileReady) return; + + return DocumentOpenLink::doOpen(data, 2); +} + +void GifOpenLink::onClick(Qt::MouseButton button) const { + if (button != Qt::LeftButton) return; + doOpen(document()); +} + void DocumentSaveLink::doSave(DocumentData *data, bool forceSavingAs) { if (!data->date) return; diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 02a93c0fd..0af6f20c3 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1235,6 +1235,16 @@ class DocumentOpenLink : public DocumentLink { public: DocumentOpenLink(DocumentData *document) : DocumentLink(document) { } + static void doOpen(DocumentData *document, int32 openOnSave = 1); + void onClick(Qt::MouseButton button) const; +}; + +class GifOpenLink : public DocumentOpenLink { + TEXT_LINK_CLASS(GifOpenLink) + +public: + GifOpenLink(DocumentData *document) : DocumentOpenLink(document) { + } static void doOpen(DocumentData *document); void onClick(Qt::MouseButton button) const; };