mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
files overview redesign done
This commit is contained in:
parent
cc004d435b
commit
0fd6f04aa9
17 changed files with 596 additions and 382 deletions
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 176 KiB |
Binary file not shown.
Before Width: | Height: | Size: 237 KiB After Width: | Height: | Size: 237 KiB |
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue