new layout items structure started

This commit is contained in:
John Preston 2015-12-20 17:05:07 +03:00
parent 7d8c45ec92
commit cc004d435b
18 changed files with 1056 additions and 389 deletions

View File

@ -2185,7 +2185,7 @@ mediaviewLoaderSkip: 9px;
minPhotoSize: 104px;
maxMediaSize: 420px;
maxStickerSize: 256px;
maxGifSize: 256px;
maxGifSize: 320px;
downloadPathSkip: 10px;
@ -2196,7 +2196,7 @@ usernameTextStyle: textStyle(defaultTextStyle) {
}
usernameDefaultFg: #777;
youtubeIcon: sprite(116px, 338px, 90px, 62px);
youtubeIcon: sprite(116px, 338px, 72px, 50px);
videoIcon: sprite(0px, 340px, 60px, 60px);
locationSize: size(320px, 240px);

View File

@ -32,6 +32,7 @@ class Color;
class FileUploader;
#include "history.h"
#include "layout.h"
typedef QMap<HistoryItem*, NullType> HistoryItemsMap;
typedef QMap<VideoData*, HistoryItemsMap> VideoItems;

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

View File

@ -22,7 +22,6 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
#include "style.h"
#include "lang.h"
#include "history.h"
#include "mainwidget.h"
#include "application.h"
#include "fileuploader.h"
@ -35,43 +34,6 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
#include "audio.h"
#include "localstorage.h"
TextParseOptions _textNameOptions = {
0, // flags
4096, // maxw
1, // maxh
Qt::LayoutDirectionAuto, // lang-dependent
};
TextParseOptions _textDlgOptions = {
0, // flags
0, // maxw is style-dependent
1, // maxh
Qt::LayoutDirectionAuto, // lang-dependent
};
TextParseOptions _historyTextOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText | TextParseMono, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historyBotOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseBotCommands | TextParseMultiline | TextParseRichText | TextParseMono, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historyTextNoMonoOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historyBotNoMonoOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseBotCommands | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
namespace {
TextParseOptions _historySrvOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
@ -135,20 +97,6 @@ namespace {
}
}
const TextParseOptions &itemTextOptions(History *h, PeerData *f) {
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isMegagroup() && h->peer->asChannel()->mgInfo->botStatus >= 0)) {
return _historyBotOptions;
}
return _historyTextOptions;
}
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f) {
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isMegagroup() && h->peer->asChannel()->mgInfo->botStatus >= 0)) {
return _historyBotNoMonoOptions;
}
return _historyTextNoMonoOptions;
}
void historyInit() {
_initTextOptions();
}
@ -4343,6 +4291,97 @@ 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 {
@ -6174,12 +6213,12 @@ bool HistoryMessage::uploading() const {
}
QString HistoryMessage::selectedText(uint32 selection) const {
if (_media && selection == FullItemSel) {
if (_media && selection == FullSelection) {
QString text = _text.original(0, 0xFFFF, Text::ExpandLinksAll), mediaText = _media->inHistoryText();
return text.isEmpty() ? mediaText : (mediaText.isEmpty() ? text : (text + ' ' + mediaText));
}
uint16 selectedFrom = (selection == FullItemSel) ? 0 : ((selection >> 16) & 0xFFFF);
uint16 selectedTo = (selection == FullItemSel) ? 0xFFFF : (selection & 0xFFFF);
uint16 selectedFrom = (selection == FullSelection) ? 0 : ((selection >> 16) & 0xFFFF);
uint16 selectedTo = (selection == FullSelection) ? 0xFFFF : (selection & 0xFFFF);
return _text.original(selectedFrom, selectedTo, Text::ExpandLinksAll);
}
@ -6356,7 +6395,7 @@ void HistoryMessage::setId(MsgId newId) {
}
void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 ms) const {
bool outbg = out() && !fromChannel(), bubble = drawBubble(), selected = (selection == FullItemSel);
bool outbg = out() && !fromChannel(), bubble = drawBubble(), selected = (selection == FullSelection);
textstyleSet(&(outbg ? st::outTextStyle : st::inTextStyle));
@ -6433,8 +6472,8 @@ void HistoryMessage::draw(Painter &p, const QRect &r, uint32 selection, uint64 m
void HistoryMessage::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
p.setPen(st::msgColor->p);
p.setFont(st::msgFont->f);
uint16 selectedFrom = (selection == FullItemSel) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullItemSel) ? 0 : selection & 0xFFFF;
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF;
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignLeft, 0, -1, selectedFrom, selectedTo);
}
@ -6657,7 +6696,7 @@ HistoryForwarded::HistoryForwarded(History *history, HistoryBlock *block, MsgId
}
QString HistoryForwarded::selectedText(uint32 selection) const {
if (selection != FullItemSel) return HistoryMessage::selectedText(selection);
if (selection != FullSelection) return HistoryMessage::selectedText(selection);
QString result, original = HistoryMessage::selectedText(selection);
result.reserve(lang(lng_forwarded_from).size() + fwdFrom->name.size() + 4 + original.size());
result.append('[').append(lang(lng_forwarded_from)).append(' ').append(fwdFrom->name).append(qsl("]\n")).append(original);
@ -6705,7 +6744,7 @@ void HistoryForwarded::drawForwardedFrom(Painter &p, int32 x, int32 y, int32 w,
void HistoryForwarded::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
QRect realtrect(trect);
if (displayForwardedFrom()) {
drawForwardedFrom(p, realtrect.x(), realtrect.y(), realtrect.width(), (selection == FullItemSel));
drawForwardedFrom(p, realtrect.x(), realtrect.y(), realtrect.width(), (selection == FullSelection));
realtrect.setY(trect.y() + st::msgServiceNameFont->height);
}
HistoryMessage::drawMessageText(p, realtrect, selection);
@ -6830,7 +6869,7 @@ HistoryReply::HistoryReply(History *history, HistoryBlock *block, MsgId msgId, i
}
QString HistoryReply::selectedText(uint32 selection) const {
if (selection != FullItemSel || !replyToMsg) return HistoryMessage::selectedText(selection);
if (selection != FullSelection || !replyToMsg) return HistoryMessage::selectedText(selection);
QString result, original = HistoryMessage::selectedText(selection);
result.reserve(lang(lng_in_reply_to).size() + replyToMsg->from()->name.size() + 4 + original.size());
result.append('[').append(lang(lng_in_reply_to)).append(' ').append(replyToMsg->from()->name).append(qsl("]\n")).append(original);
@ -6970,7 +7009,7 @@ void HistoryReply::drawReplyTo(Painter &p, int32 x, int32 y, int32 w, bool selec
void HistoryReply::drawMessageText(Painter &p, const QRect &trect, uint32 selection) const {
int32 h = st::msgReplyPadding.top() + st::msgReplyBarSize.height() + st::msgReplyPadding.bottom();
drawReplyTo(p, trect.x(), trect.y(), trect.width(), (selection == FullItemSel));
drawReplyTo(p, trect.x(), trect.y(), trect.width(), (selection == FullSelection));
QRect realtrect(trect);
realtrect.setY(trect.y() + h);
@ -7248,8 +7287,8 @@ void HistoryServiceMsg::initDimensions() {
}
QString HistoryServiceMsg::selectedText(uint32 selection) const {
uint16 selectedFrom = (selection == FullItemSel) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullItemSel) ? 0xFFFF : (selection & 0xFFFF);
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullSelection) ? 0xFFFF : (selection & 0xFFFF);
return _text.original(selectedFrom, selectedTo);
}
@ -7295,7 +7334,7 @@ void HistoryServiceMsg::draw(Painter &p, const QRect &r, uint32 selection, uint6
p.save();
int32 left = st::msgServiceMargin.left() + (width - _media->maxWidth()) / 2, top = st::msgServiceMargin.top() + height + st::msgServiceMargin.top();
p.translate(left, top);
_media->draw(p, this, r.translated(-left, -top), selection == FullItemSel, ms);
_media->draw(p, this, r.translated(-left, -top), selection == FullSelection, ms);
p.restore();
}
@ -7305,13 +7344,13 @@ void HistoryServiceMsg::draw(Painter &p, const QRect &r, uint32 selection, uint6
left += (width - _maxw) / 2;
width = _maxw;
}
App::roundRect(p, left, st::msgServiceMargin.top(), width, height, App::msgServiceBg(), (selection == FullItemSel) ? ServiceSelectedCorners : ServiceCorners);
App::roundRect(p, left, st::msgServiceMargin.top(), width, height, App::msgServiceBg(), (selection == FullSelection) ? ServiceSelectedCorners : ServiceCorners);
p.setBrush(Qt::NoBrush);
p.setPen(st::msgServiceColor->p);
p.setFont(st::msgServiceFont->f);
uint16 selectedFrom = (selection == FullItemSel) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullItemSel) ? 0 : selection & 0xFFFF;
uint16 selectedFrom = (selection == FullSelection) ? 0 : (selection >> 16) & 0xFFFF;
uint16 selectedTo = (selection == FullSelection) ? 0 : selection & 0xFFFF;
_text.draw(p, trect.x(), trect.y(), trect.width(), Qt::AlignCenter, 0, -1, selectedFrom, selectedTo);
textstyleRestore();
}

View File

@ -24,13 +24,8 @@ void historyInit();
class HistoryItem;
static const uint32 FullItemSel = 0xFFFFFFFF;
typedef QMap<int32, HistoryItem*> SelectedItemSet;
extern TextParseOptions _textNameOptions, _textDlgOptions;
extern TextParseOptions _historyTextOptions, _historyBotOptions, _historyTextNoMonoOptions, _historyBotNoMonoOptions;
#include "structs.h"
enum NewMessageType {
@ -765,25 +760,25 @@ public:
class HistoryElem {
public:
HistoryElem() : _height(0), _maxw(0) {
HistoryElem() : _maxw(0), _minh(0), _height(0) {
}
int32 height() const {
return _height;
}
int32 maxWidth() const {
return _maxw;
}
int32 minHeight() const {
return _minh;
}
int32 height() const {
return _height;
}
virtual ~HistoryElem() {
}
protected:
mutable int32 _height, _maxw, _minh;
mutable int32 _maxw, _minh, _height;
HistoryElem &operator=(const HistoryElem &);
};
@ -1316,6 +1311,7 @@ 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 {
@ -2393,6 +2389,3 @@ protected:
QString text;
bool freezed;
};
const TextParseOptions &itemTextOptions(History *h, PeerData *f);
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f);

View File

@ -182,7 +182,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
if (r.y() < y + item->height()) while (y < drawToY) {
uint32 sel = 0;
if (y >= selfromy && y < seltoy) {
sel = (_dragSelecting && !item->serviceMsg() && item->id > 0) ? FullItemSel : 0;
sel = (_dragSelecting && !item->serviceMsg() && item->id > 0) ? FullSelection : 0;
} else if (hasSel) {
SelectedItems::const_iterator i = _selected.constFind(item);
if (i != selEnd) {
@ -226,7 +226,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
if (r.y() < y + h && hdrawtop < y + h) {
uint32 sel = 0;
if (y >= selfromy && y < seltoy) {
sel = (_dragSelecting && !item->serviceMsg() && item->id > 0) ? FullItemSel : 0;
sel = (_dragSelecting && !item->serviceMsg() && item->id > 0) ? FullSelection : 0;
} else if (hasSel) {
SelectedItems::const_iterator i = _selected.constFind(item);
if (i != selEnd) {
@ -495,7 +495,7 @@ void HistoryInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton butt
if (textlnkDown()) {
_dragAction = PrepareDrag;
} else if (!_selected.isEmpty()) {
if (_selected.cbegin().value() == FullItemSel) {
if (_selected.cbegin().value() == FullSelection) {
if (_selected.constFind(_dragItem) != _selected.cend() && App::hoveredItem()) {
_dragAction = PrepareDrag; // start items drag
} else if (!_dragWasInactive) {
@ -510,7 +510,7 @@ void HistoryInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton butt
_dragItem->getSymbol(symbol, afterDragSymbol, uponSymbol, _dragStartPos.x(), _dragStartPos.y());
if (uponSymbol) {
uint32 selStatus = (symbol << 16) | symbol;
if (selStatus != FullItemSel && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) {
if (selStatus != FullSelection && (_selected.isEmpty() || _selected.cbegin().value() != FullSelection)) {
if (!_selected.isEmpty()) {
redrawItem(_selected.cbegin().key());
_selected.clear();
@ -532,7 +532,7 @@ void HistoryInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton butt
bool uponSelected = uponSymbol;
if (uponSelected) {
if (_selected.isEmpty() ||
_selected.cbegin().value() == FullItemSel ||
_selected.cbegin().value() == FullSelection ||
_selected.cbegin().key() != _dragItem
) {
uponSelected = false;
@ -551,7 +551,7 @@ void HistoryInner::dragActionStart(const QPoint &screenPos, Qt::MouseButton butt
} else {
if (afterDragSymbol) ++_dragSymbol;
uint32 selStatus = (_dragSymbol << 16) | _dragSymbol;
if (selStatus != FullItemSel && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) {
if (selStatus != FullSelection && (_selected.isEmpty() || _selected.cbegin().value() != FullSelection)) {
if (!_selected.isEmpty()) {
redrawItem(_selected.cbegin().key());
_selected.clear();
@ -593,13 +593,13 @@ void HistoryInner::onDragExec() {
if (_dragItem) {
bool afterDragSymbol;
uint16 symbol;
if (!_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
if (!_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
uponSelected = _selected.contains(_dragItem);
} else {
_dragItem->getSymbol(symbol, afterDragSymbol, uponSelected, _dragStartPos.x(), _dragStartPos.y());
if (uponSelected) {
if (_selected.isEmpty() ||
_selected.cbegin().value() == FullItemSel ||
_selected.cbegin().value() == FullSelection ||
_selected.cbegin().key() != _dragItem
) {
uponSelected = false;
@ -631,7 +631,7 @@ void HistoryInner::onDragExec() {
mimeData->setText(sel);
if (!urls.isEmpty()) mimeData->setUrls(urls);
if (uponSelected && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel && cWideMode()) {
if (uponSelected && !_selected.isEmpty() && _selected.cbegin().value() == FullSelection && cWideMode()) {
mimeData->setData(qsl("application/x-td-forward-selected"), "1");
}
drag->setMimeData(mimeData);
@ -723,7 +723,7 @@ void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton but
lnkAudio = (lnkType == qstr("AudioOpenLink")),
lnkDocument = (lnkType == qstr("DocumentOpenLink")),
lnkContact = (lnkType == qstr("PeerLink") && dynamic_cast<HistoryContact*>(App::pressedLinkItem() ? App::pressedLinkItem()->getMedia() : 0));
if (_dragAction == PrepareDrag && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel && button != Qt::RightButton) {
if (_dragAction == PrepareDrag && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullSelection && button != Qt::RightButton) {
if (lnkPhoto || lnkVideo || lnkAudio || lnkDocument || lnkContact) {
needClick = TextLinkPtr();
}
@ -752,14 +752,14 @@ void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton but
dragActionCancel();
return;
}
if (_dragAction == PrepareSelect && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
if (_dragAction == PrepareSelect && !_dragWasInactive && !_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
SelectedItems::iterator i = _selected.find(_dragItem);
if (i == _selected.cend() && !_dragItem->serviceMsg() && _dragItem->id > 0) {
if (_selected.size() < MaxSelectedItems) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullSelection) {
_selected.clear();
}
_selected.insert(_dragItem, FullItemSel);
_selected.insert(_dragItem, FullSelection);
}
} else {
_selected.erase(i);
@ -767,12 +767,12 @@ void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton but
redrawItem(_dragItem);
} else if (_dragAction == PrepareDrag && !_dragWasInactive && button != Qt::RightButton) {
SelectedItems::iterator i = _selected.find(_dragItem);
if (i != _selected.cend() && i.value() == FullItemSel) {
if (i != _selected.cend() && i.value() == FullSelection) {
_selected.erase(i);
redrawItem(_dragItem);
} else if (i == _selected.cend() && !_dragItem->serviceMsg() && _dragItem->id > 0 && !_selected.isEmpty() && _selected.cbegin().value() == FullItemSel) {
} else if (i == _selected.cend() && !_dragItem->serviceMsg() && _dragItem->id > 0 && !_selected.isEmpty() && _selected.cbegin().value() == FullSelection) {
if (_selected.size() < MaxSelectedItems) {
_selected.insert(_dragItem, FullItemSel);
_selected.insert(_dragItem, FullSelection);
redrawItem(_dragItem);
}
} else {
@ -785,7 +785,7 @@ void HistoryInner::dragActionFinish(const QPoint &screenPos, Qt::MouseButton but
_dragSelFrom = _dragSelTo = 0;
} else if (!_selected.isEmpty() && !_dragWasInactive) {
uint32 sel = _selected.cbegin().value();
if (sel != FullItemSel && (sel & 0xFFFF) == ((sel >> 16) & 0xFFFF)) {
if (sel != FullSelection && (sel & 0xFFFF) == ((sel >> 16) & 0xFFFF)) {
_selected.clear();
if (App::wnd()) App::wnd()->setInnerFocus();
}
@ -807,7 +807,7 @@ void HistoryInner::mouseReleaseEvent(QMouseEvent *e) {
void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) {
if (!_history) return;
if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel))) && _dragSelType == TextSelectLetters && _dragItem) {
if (((_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullSelection) || (_dragAction == NoDrag && (_selected.isEmpty() || _selected.cbegin().value() != FullSelection))) && _dragSelType == TextSelectLetters && _dragItem) {
bool afterDragSymbol, uponSelected;
uint16 symbol;
_dragItem->getSymbol(symbol, afterDragSymbol, uponSelected, _dragStartPos.x(), _dragStartPos.y());
@ -850,7 +850,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
int32 isUponSelected = 0, hasSelected = 0;;
if (!_selected.isEmpty()) {
isUponSelected = -1;
if (_selected.cbegin().value() == FullItemSel) {
if (_selected.cbegin().value() == FullSelection) {
hasSelected = 2;
if (App::hoveredItem() && _selected.constFind(App::hoveredItem()) != _selected.cend()) {
isUponSelected = 2;
@ -947,7 +947,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
_menu->addAction(lang(doc->sticker()->setInstalled() ? lng_context_pack_info : lng_context_pack_add), _widget, SLOT(onStickerPackInfo()));
}
}
QString contextMenuText = item->selectedText(FullItemSel);
QString contextMenuText = item->selectedText(FullSelection);
if (!contextMenuText.isEmpty() && (!msg || !msg->getMedia() || msg->getMedia()->type() != MediaTypeSticker)) {
_menu->addAction(lang(lng_context_copy_text), this, SLOT(copyContextText()))->setEnabled(true);
}
@ -1098,7 +1098,7 @@ void HistoryInner::copyContextText() {
return;
}
QString contextMenuText = item->selectedText(FullItemSel);
QString contextMenuText = item->selectedText(FullSelection);
if (!contextMenuText.isEmpty()) {
QApplication::clipboard()->setText(contextMenuText);
}
@ -1116,7 +1116,7 @@ QString HistoryInner::getSelectedText() const {
}
if (sel.isEmpty()) return QString();
if (sel.cbegin().value() != FullItemSel) {
if (sel.cbegin().value() != FullSelection) {
return sel.cbegin().key()->selectedText(sel.cbegin().value());
}
@ -1127,7 +1127,7 @@ QString HistoryInner::getSelectedText() const {
HistoryItem *item = i.key();
if (item->detached()) continue;
QString text, sel = item->selectedText(FullItemSel), time = item->date.toString(timeFormat);
QString text, sel = item->selectedText(FullSelection), time = item->date.toString(timeFormat);
int32 size = item->from()->name.size() + time.size() + sel.size();
text.reserve(size);
@ -1449,7 +1449,7 @@ bool HistoryInner::canCopySelected() const {
}
bool HistoryInner::canDeleteSelected() const {
if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return false;
if (_selected.isEmpty() || _selected.cbegin().value() != FullSelection) return false;
int32 selectedForForward, selectedForDelete;
getSelectionState(selectedForForward, selectedForDelete);
return (selectedForForward == selectedForDelete);
@ -1458,7 +1458,7 @@ bool HistoryInner::canDeleteSelected() const {
void HistoryInner::getSelectionState(int32 &selectedForForward, int32 &selectedForDelete) const {
selectedForForward = selectedForDelete = 0;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
if (i.key()->type() == HistoryItemMsg && i.value() == FullItemSel) {
if (i.key()->type() == HistoryItemMsg && i.value() == FullSelection) {
if (i.key()->canDelete()) {
++selectedForDelete;
}
@ -1471,7 +1471,7 @@ void HistoryInner::getSelectionState(int32 &selectedForForward, int32 &selectedF
}
void HistoryInner::clearSelectedItems(bool onlyTextSelection) {
if (!_selected.isEmpty() && (!onlyTextSelection || _selected.cbegin().value() != FullItemSel)) {
if (!_selected.isEmpty() && (!onlyTextSelection || _selected.cbegin().value() != FullSelection)) {
_selected.clear();
_widget->updateTopBarSelection();
_widget->update();
@ -1479,7 +1479,7 @@ void HistoryInner::clearSelectedItems(bool onlyTextSelection) {
}
void HistoryInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
if (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel) return;
if (_selected.isEmpty() || _selected.cbegin().value() != FullSelection) return;
for (SelectedItems::const_iterator i = _selected.cbegin(), e = _selected.cend(); i != e; ++i) {
HistoryItem *item = i.key();
@ -1494,12 +1494,12 @@ void HistoryInner::fillSelectedItems(SelectedItemSet &sel, bool forDelete) {
}
void HistoryInner::selectItem(HistoryItem *item) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
if (!_selected.isEmpty() && _selected.cbegin().value() != FullSelection) {
_selected.clear();
} else if (_selected.size() == MaxSelectedItems && _selected.constFind(item) == _selected.cend()) {
return;
}
_selected.insert(item, FullItemSel);
_selected.insert(item, FullSelection);
_widget->updateTopBarSelection();
_widget->update();
}
@ -1589,7 +1589,7 @@ void HistoryInner::onUpdateSelected() {
_dragCursorState = cursorState;
if (lnk) {
cur = style::cur_pointer;
} else if (_dragCursorState == HistoryInTextCursorState && (_selected.isEmpty() || _selected.cbegin().value() != FullItemSel)) {
} else if (_dragCursorState == HistoryInTextCursorState && (_selected.isEmpty() || _selected.cbegin().value() != FullSelection)) {
cur = style::cur_text;
} else if (_dragCursorState == HistoryInDateCursorState) {
// cur = style::cur_cross;
@ -1606,14 +1606,14 @@ void HistoryInner::onUpdateSelected() {
cur = textlnkDown() ? style::cur_pointer : style::cur_default;
if (_dragAction == Selecting) {
bool canSelectMany = (_history != 0);
if (item == _dragItem && item == App::hoveredItem() && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
if (item == _dragItem && item == App::hoveredItem() && !_selected.isEmpty() && _selected.cbegin().value() != FullSelection) {
bool afterSymbol, uponSymbol;
uint16 second;
_dragItem->getSymbol(second, afterSymbol, uponSymbol, m.x(), m.y());
if (afterSymbol && _dragSelType == TextSelectLetters) ++second;
uint32 selState = _dragItem->adjustSelection(qMin(second, _dragSymbol), qMax(second, _dragSymbol), _dragSelType);
_selected[_dragItem] = selState;
if (!_wasSelectedText && (selState == FullItemSel || (selState & 0xFFFF) != ((selState >> 16) & 0xFFFF))) {
if (!_wasSelectedText && (selState == FullSelection || (selState & 0xFFFF) != ((selState >> 16) & 0xFFFF))) {
_wasSelectedText = true;
setFocus();
}
@ -1650,7 +1650,7 @@ void HistoryInner::onUpdateSelected() {
}
if (dragFirstAffected) {
SelectedItems::const_iterator i = _selected.constFind(dragFirstAffected);
dragSelecting = (i == _selected.cend() || i.value() != FullItemSel);
dragSelecting = (i == _selected.cend() || i.value() != FullSelection);
}
updateDragSelection(dragSelFrom, dragSelTo, dragSelecting);
}
@ -1659,7 +1659,7 @@ void HistoryInner::onUpdateSelected() {
if (textlnkDown()) {
cur = style::cur_pointer;
} else if (_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullItemSel) {
} else if (_dragAction == Selecting && !_selected.isEmpty() && _selected.cbegin().value() != FullSelection) {
if (!_dragSelFrom || !_dragSelTo) {
cur = style::cur_text;
}
@ -1754,9 +1754,9 @@ void HistoryInner::addSelectionRange(SelectedItems *toItems, int32 fromblock, in
if (item->id > 0 && !item->serviceMsg()) {
if (i == toItems->cend()) {
if (toItems->size() >= MaxSelectedItems) break;
toItems->insert(item, FullItemSel);
} else if (i.value() != FullItemSel) {
*i = FullItemSel;
toItems->insert(item, FullSelection);
} else if (i.value() != FullSelection) {
*i = FullSelection;
}
} else {
if (i != toItems->cend()) {
@ -1777,7 +1777,7 @@ void HistoryInner::applyDragSelection(SelectedItems *toItems) const {
}
seltoy += _dragSelTo->height();
if (!toItems->isEmpty() && toItems->cbegin().value() != FullItemSel) {
if (!toItems->isEmpty() && toItems->cbegin().value() != FullSelection) {
toItems->clear();
}
if (_dragSelecting) {

View File

@ -0,0 +1,199 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
*/
#include "stdafx.h"
#include "style.h"
#include "lang.h"
#include "mainwidget.h"
#include "application.h"
#include "fileuploader.h"
#include "window.h"
#include "gui/filedialog.h"
#include "boxes/addcontactbox.h"
#include "boxes/confirmbox.h"
#include "audio.h"
#include "localstorage.h"
TextParseOptions _textNameOptions = {
0, // flags
4096, // maxw
1, // maxh
Qt::LayoutDirectionAuto, // lang-dependent
};
TextParseOptions _textDlgOptions = {
0, // flags
0, // maxw is style-dependent
1, // maxh
Qt::LayoutDirectionAuto, // lang-dependent
};
TextParseOptions _historyTextOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText | TextParseMono, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historyBotOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseBotCommands | TextParseMultiline | TextParseRichText | TextParseMono, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historyTextNoMonoOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _historyBotNoMonoOptions = {
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseBotCommands | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
};
const TextParseOptions &itemTextOptions(History *h, PeerData *f) {
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isMegagroup() && h->peer->asChannel()->mgInfo->botStatus >= 0)) {
return _historyBotOptions;
}
return _historyTextOptions;
}
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f) {
if ((h->peer->isUser() && h->peer->asUser()->botInfo) || (f->isUser() && f->asUser()->botInfo) || (h->peer->isChat() && h->peer->asChat()->botStatus >= 0) || (h->peer->isMegagroup() && h->peer->asChannel()->mgInfo->botStatus >= 0)) {
return _historyBotNoMonoOptions;
}
return _historyTextNoMonoOptions;
}
void LayoutRadialProgressItem::linkOver(const TextLinkPtr &lnk) {
if (lnk == _savel || lnk == _cancell) {
a_iconOver.start(1);
_a_iconOver.start();
}
}
void LayoutRadialProgressItem::linkOut(const TextLinkPtr &lnk) {
if (lnk == _savel || lnk == _cancell) {
a_iconOver.start(0);
_a_iconOver.start();
}
}
void LayoutRadialProgressItem::setLinks(ITextLink *openl, ITextLink *savel, ITextLink *cancell) {
_openl.reset(openl);
_savel.reset(savel);
_cancell.reset(cancell);
}
void LayoutRadialProgressItem::step_iconOver(float64 ms, bool timer) {
float64 dt = ms / st::msgFileOverDuration;
if (dt >= 1) {
a_iconOver.finish();
_a_iconOver.stop();
} else {
a_iconOver.update(dt, anim::linear);
}
if (timer && iconAnimated()) {
Ui::redrawHistoryItem(_parent);
}
}
void LayoutRadialProgressItem::step_radial(uint64 ms, bool timer) {
_radial->update(dataProgress(), dataFinished(), ms);
if (!_radial->animating()) {
checkRadialFinished();
}
if (timer) {
Ui::redrawHistoryItem(_parent);
}
}
void LayoutRadialProgressItem::ensureRadial() const {
if (!_radial) {
_radial = new RadialAnimation(
st::msgFileRadialLine,
animation(const_cast<LayoutRadialProgressItem*>(this), &LayoutRadialProgressItem::step_radial));
}
}
void LayoutRadialProgressItem::checkRadialFinished() {
if (_radial && !_radial->animating() && dataLoaded()) {
delete _radial;
_radial = 0;
}
}
LayoutRadialProgressItem::~LayoutRadialProgressItem() {
if (_radial) {
delete _radial;
setBadPointer(_radial);
}
}
void LayoutAbstractFileItem::setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const {
_statusSize = newSize;
if (_statusSize == FileStatusSizeReady) {
_statusText = (duration >= 0) ? formatDurationAndSizeText(duration, fullSize) : (duration < -1 ? formatGifAndSizeText(fullSize) : formatSizeText(fullSize));
} else if (_statusSize == FileStatusSizeLoaded) {
_statusText = (duration >= 0) ? formatDurationText(duration) : (duration < -1 ? qsl("GIF") : formatSizeText(fullSize));
} else if (_statusSize == FileStatusSizeFailed) {
_statusText = lang(lng_attach_failed);
} else if (_statusSize >= 0) {
_statusText = formatDownloadText(_statusSize, fullSize);
} else {
_statusText = formatPlayedText(-_statusSize - 1, realDuration);
}
}
LayoutOverviewDate::LayoutOverviewDate(const QDate &date, int32 top)
: _info(top)
, _date(date)
, _text(langDayOfMonth(date)) {
}
void LayoutOverviewDate::initDimensions() {
_maxw = st::normalFont->width(_text);
_minh = st::linksDateMargin + st::normalFont->height + st::linksDateMargin + st::linksBorder;
}
void LayoutOverviewDate::paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const {
if (clip.intersects(QRect(0, st::linksDateMargin, _width, st::normalFont->height))) {
p.setPen(st::linksDateColor);
p.setFont(st::normalFont);
p.drawTextLeft(0, st::linksDateMargin, _width, _text);
}
}
LayoutOverviewDocument::LayoutOverviewDocument(DocumentData *document, HistoryItem *parent, int32 top) : LayoutAbstractFileItem(parent)
, _info(top)
, _data(document) {
}
void LayoutOverviewDocument::initDimensions() {
_maxw = st::profileMaxWidth;
_minh = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
}
void LayoutOverviewDocument::paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const {
}

View File

@ -0,0 +1,277 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
*/
#pragma once
static const uint32 FullSelection = 0xFFFFFFFF;
extern TextParseOptions _textNameOptions, _textDlgOptions;
extern TextParseOptions _historyTextOptions, _historyBotOptions, _historyTextNoMonoOptions, _historyBotNoMonoOptions;
const TextParseOptions &itemTextOptions(History *h, PeerData *f);
const TextParseOptions &itemTextNoMonoOptions(History *h, PeerData *f);
class LayoutMediaItem;
class OverviewItemInfo;
class LayoutItem {
public:
LayoutItem() : _maxw(0), _minh(0) {
}
int32 maxWidth() const {
return _maxw;
}
int32 minHeight() const {
return _minh;
}
virtual void initDimensions() = 0;
virtual int32 resizeGetHeight(int32 width) {
_width = qMin(width, _maxw);
_height = _minh;
return _height;
}
virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const = 0;
virtual void getState(TextLinkPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
link = TextLinkPtr();
cursor = HistoryDefaultCursorState;
}
virtual void getSymbol(uint16 &symbol, bool &after, bool &upon, int32 x, int32 y) const { // from text
upon = hasPoint(x, y);
symbol = upon ? 0xFFFF : 0;
after = false;
}
virtual void linkOver(const TextLinkPtr &lnk) {
}
virtual void linkOut(const TextLinkPtr &lnk) {
}
int32 width() const {
return _width;
}
int32 height() const {
return _height;
}
bool hasPoint(int32 x, int32 y) const {
return (x >= 0 && y >= 0 && x < width() && y < height());
}
virtual ~LayoutItem() {
}
virtual LayoutMediaItem *toLayoutMediaItem() {
return 0;
}
virtual const LayoutMediaItem *toLayoutMediaItem() const {
return 0;
}
virtual HistoryItem *getItem() const {
return 0;
}
virtual DocumentData *getDocument() const {
return 0;
}
virtual OverviewItemInfo *getOverviewItemInfo() {
return 0;
}
virtual const OverviewItemInfo *getOverviewItemInfo() const {
return 0;
}
MsgId msgId() const {
const HistoryItem *item = getItem();
return item ? item->id : 0;
}
protected:
int32 _width, _height, _maxw, _minh;
LayoutItem &operator=(const LayoutItem &);
};
class LayoutMediaItem : public LayoutItem {
public:
LayoutMediaItem(HistoryItem *parent) : _parent(parent) {
}
virtual LayoutMediaItem *toLayoutMediaItem() {
return this;
}
virtual const LayoutMediaItem *toLayoutMediaItem() const {
return this;
}
virtual HistoryItem *getItem() const {
return _parent;
}
protected:
HistoryItem *_parent;
};
class LayoutRadialProgressItem : public LayoutMediaItem {
public:
LayoutRadialProgressItem(HistoryItem *parent) : LayoutMediaItem(parent)
, _radial(0)
, a_iconOver(0, 0)
, _a_iconOver(animation(this, &LayoutRadialProgressItem::step_iconOver)) {
}
void linkOver(const TextLinkPtr &lnk);
void linkOut(const TextLinkPtr &lnk);
~LayoutRadialProgressItem();
protected:
TextLinkPtr _openl, _savel, _cancell;
void setLinks(ITextLink *openl, ITextLink *savel, ITextLink *cancell);
void step_iconOver(float64 ms, bool timer);
void step_radial(uint64 ms, bool timer);
void ensureRadial() const;
void checkRadialFinished();
bool isRadialAnimation(uint64 ms) const {
if (!_radial || !_radial->animating()) return false;
_radial->step(ms);
return _radial && _radial->animating();
}
virtual float64 dataProgress() const = 0;
virtual bool dataFinished() const = 0;
virtual bool dataLoaded() const = 0;
virtual bool iconAnimated() const {
return false;
}
mutable RadialAnimation *_radial;
anim::fvalue a_iconOver;
Animation _a_iconOver;
private:
LayoutRadialProgressItem(const LayoutRadialProgressItem &other);
};
class LayoutAbstractFileItem : public LayoutRadialProgressItem {
public:
LayoutAbstractFileItem(HistoryItem *parent) : LayoutRadialProgressItem(parent) {
}
protected:
// >= 0 will contain download / upload string, _statusSize = loaded bytes
// < 0 will contain played string, _statusSize = -(seconds + 1) played
// 0x7FFFFFF0 will contain status for not yet downloaded file
// 0x7FFFFFF1 will contain status for already downloaded file
// 0x7FFFFFF2 will contain status for failed to download / upload file
mutable int32 _statusSize;
mutable QString _statusText;
// duration = -1 - no duration, duration = -2 - "GIF" duration
void setStatusSize(int32 newSize, int32 fullSize, int32 duration, qint64 realDuration) const;
};
class OverviewItemInfo {
public:
OverviewItemInfo(int32 top) : _top(top) {
}
int32 top() const {
return _top;
}
void setTop(int32 top) {
_top = top;
}
private:
int32 _top;
};
class LayoutOverviewDate : public LayoutItem {
public:
LayoutOverviewDate(const QDate &date, int32 top);
virtual void initDimensions();
virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const;
virtual OverviewItemInfo *getOverviewItemInfo() {
return &_info;
}
virtual const OverviewItemInfo *getOverviewItemInfo() const {
return &_info;
}
private:
OverviewItemInfo _info;
QDate _date;
QString _text;
};
class LayoutOverviewDocument : public LayoutAbstractFileItem {
public:
LayoutOverviewDocument(DocumentData *document, HistoryItem *parent, int32 top);
virtual void initDimensions();
virtual void paint(Painter &p, const QRect &clip, uint32 selection, uint64 ms) const;
virtual DocumentData *getDocument() const {
return _data;
}
virtual OverviewItemInfo *getOverviewItemInfo() {
return &_info;
}
virtual const OverviewItemInfo *getOverviewItemInfo() const {
return &_info;
}
protected:
virtual float64 dataProgress() const {
return _data->progress();
}
virtual bool dataFinished() const {
return !_data->loader;
}
virtual bool dataLoaded() const {
return !_data->already().isEmpty() || !_data->data.isEmpty();
}
virtual bool iconAnimated() const {
return !dataLoaded() || (_radial && _radial->animating());
}
private:
OverviewItemInfo _info;
DocumentData *_data;
QString _name, _date;
int32 _namew, _datew;
int32 _thumbw;
bool withThumb() const {
return !_data->song() && !_data->thumb->isNull() && _data->thumb->width() && _data->thumb->height();
}
};

View File

@ -4248,7 +4248,9 @@ void _serialize_webPageExternal(MTPStringLogger &to, int32 stage, int32 lev, Typ
case 7: to.add(" content_url: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_content_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 4 IN FIELD flags ]"); } break;
case 8: to.add(" w: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_w) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 9: to.add(" h: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_h) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 5 IN FIELD flags ]"); } break;
case 10: to.add(" duration: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 10: to.add(" embed_url: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_embed_url) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 11: to.add(" embed_type: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_embed_type) { types.push_back(mtpc_string); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 6 IN FIELD flags ]"); } break;
case 12: to.add(" duration: "); ++stages.back(); if (flag & MTPDwebPageExternal::flag_duration) { types.push_back(mtpc_int); vtypes.push_back(0); stages.push_back(0); flags.push_back(0); } else { to.add("[ SKIPPED BY BIT 7 IN FIELD flags ]"); } break;
default: to.add("}"); types.pop_back(); vtypes.pop_back(); stages.pop_back(); flags.pop_back(); break;
}
}

View File

@ -380,7 +380,7 @@ enum {
mtpc_webPageEmpty = 0xeb1477e8,
mtpc_webPagePending = 0xc586da1c,
mtpc_webPage = 0xca820ed7,
mtpc_webPageExternal = 0xcf73f207,
mtpc_webPageExternal = 0xbb54b77,
mtpc_authorization = 0x7bf2e6f6,
mtpc_account_authorizations = 0x1250abde,
mtpc_account_noPassword = 0x96dabc18,
@ -7606,7 +7606,7 @@ private:
friend MTPwebPage MTP_webPageEmpty(const MTPlong &_id);
friend MTPwebPage MTP_webPagePending(const MTPlong &_id, MTPint _date);
friend MTPwebPage MTP_webPage(MTPint _flags, const MTPlong &_id, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_site_name, const MTPstring &_title, const MTPstring &_description, const MTPPhoto &_photo, const MTPstring &_embed_url, const MTPstring &_embed_type, MTPint _embed_width, MTPint _embed_height, MTPint _duration, const MTPstring &_author, const MTPDocument &_document);
friend MTPwebPage MTP_webPageExternal(MTPint _flags, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_title, const MTPstring &_description, const MTPstring &_thumb_url, const MTPstring &_content_url, MTPint _w, MTPint _h, MTPint _duration);
friend MTPwebPage MTP_webPageExternal(MTPint _flags, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_title, const MTPstring &_description, const MTPstring &_thumb_url, const MTPstring &_content_url, MTPint _w, MTPint _h, const MTPstring &_embed_url, const MTPstring &_embed_type, MTPint _duration);
mtpTypeId _type;
};
@ -12299,7 +12299,7 @@ class MTPDwebPageExternal : public mtpDataImpl<MTPDwebPageExternal> {
public:
MTPDwebPageExternal() {
}
MTPDwebPageExternal(MTPint _flags, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_title, const MTPstring &_description, const MTPstring &_thumb_url, const MTPstring &_content_url, MTPint _w, MTPint _h, MTPint _duration) : vflags(_flags), vurl(_url), vdisplay_url(_display_url), vtype(_type), vtitle(_title), vdescription(_description), vthumb_url(_thumb_url), vcontent_url(_content_url), vw(_w), vh(_h), vduration(_duration) {
MTPDwebPageExternal(MTPint _flags, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_title, const MTPstring &_description, const MTPstring &_thumb_url, const MTPstring &_content_url, MTPint _w, MTPint _h, const MTPstring &_embed_url, const MTPstring &_embed_type, MTPint _duration) : vflags(_flags), vurl(_url), vdisplay_url(_display_url), vtype(_type), vtitle(_title), vdescription(_description), vthumb_url(_thumb_url), vcontent_url(_content_url), vw(_w), vh(_h), vembed_url(_embed_url), vembed_type(_embed_type), vduration(_duration) {
}
MTPint vflags;
@ -12312,6 +12312,8 @@ public:
MTPstring vcontent_url;
MTPint vw;
MTPint vh;
MTPstring vembed_url;
MTPstring vembed_type;
MTPint vduration;
enum {
@ -12322,7 +12324,9 @@ public:
flag_content_url = (1 << 4),
flag_w = (1 << 5),
flag_h = (1 << 5),
flag_duration = (1 << 6),
flag_embed_url = (1 << 6),
flag_embed_type = (1 << 6),
flag_duration = (1 << 7),
};
bool has_type() const { return vflags.v & flag_type; }
@ -12332,6 +12336,8 @@ public:
bool has_content_url() const { return vflags.v & flag_content_url; }
bool has_w() const { return vflags.v & flag_w; }
bool has_h() const { return vflags.v & flag_h; }
bool has_embed_url() const { return vflags.v & flag_embed_url; }
bool has_embed_type() const { return vflags.v & flag_embed_type; }
bool has_duration() const { return vflags.v & flag_duration; }
};
@ -28298,7 +28304,7 @@ inline uint32 MTPwebPage::innerLength() const {
}
case mtpc_webPageExternal: {
const MTPDwebPageExternal &v(c_webPageExternal());
return v.vflags.innerLength() + v.vurl.innerLength() + v.vdisplay_url.innerLength() + (v.has_type() ? v.vtype.innerLength() : 0) + (v.has_title() ? v.vtitle.innerLength() : 0) + (v.has_description() ? v.vdescription.innerLength() : 0) + (v.has_thumb_url() ? v.vthumb_url.innerLength() : 0) + (v.has_content_url() ? v.vcontent_url.innerLength() : 0) + (v.has_w() ? v.vw.innerLength() : 0) + (v.has_h() ? v.vh.innerLength() : 0) + (v.has_duration() ? v.vduration.innerLength() : 0);
return v.vflags.innerLength() + v.vurl.innerLength() + v.vdisplay_url.innerLength() + (v.has_type() ? v.vtype.innerLength() : 0) + (v.has_title() ? v.vtitle.innerLength() : 0) + (v.has_description() ? v.vdescription.innerLength() : 0) + (v.has_thumb_url() ? v.vthumb_url.innerLength() : 0) + (v.has_content_url() ? v.vcontent_url.innerLength() : 0) + (v.has_w() ? v.vw.innerLength() : 0) + (v.has_h() ? v.vh.innerLength() : 0) + (v.has_embed_url() ? v.vembed_url.innerLength() : 0) + (v.has_embed_type() ? v.vembed_type.innerLength() : 0) + (v.has_duration() ? v.vduration.innerLength() : 0);
}
}
return 0;
@ -28354,6 +28360,8 @@ inline void MTPwebPage::read(const mtpPrime *&from, const mtpPrime *end, mtpType
if (v.has_content_url()) { v.vcontent_url.read(from, end); } else { v.vcontent_url = MTPstring(); }
if (v.has_w()) { v.vw.read(from, end); } else { v.vw = MTPint(); }
if (v.has_h()) { v.vh.read(from, end); } else { v.vh = MTPint(); }
if (v.has_embed_url()) { v.vembed_url.read(from, end); } else { v.vembed_url = MTPstring(); }
if (v.has_embed_type()) { v.vembed_type.read(from, end); } else { v.vembed_type = MTPstring(); }
if (v.has_duration()) { v.vduration.read(from, end); } else { v.vduration = MTPint(); }
} break;
default: throw mtpErrorUnexpected(cons, "MTPwebPage");
@ -28401,6 +28409,8 @@ inline void MTPwebPage::write(mtpBuffer &to) const {
if (v.has_content_url()) v.vcontent_url.write(to);
if (v.has_w()) v.vw.write(to);
if (v.has_h()) v.vh.write(to);
if (v.has_embed_url()) v.vembed_url.write(to);
if (v.has_embed_type()) v.vembed_type.write(to);
if (v.has_duration()) v.vduration.write(to);
} break;
}
@ -28431,8 +28441,8 @@ inline MTPwebPage MTP_webPagePending(const MTPlong &_id, MTPint _date) {
inline MTPwebPage MTP_webPage(MTPint _flags, const MTPlong &_id, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_site_name, const MTPstring &_title, const MTPstring &_description, const MTPPhoto &_photo, const MTPstring &_embed_url, const MTPstring &_embed_type, MTPint _embed_width, MTPint _embed_height, MTPint _duration, const MTPstring &_author, const MTPDocument &_document) {
return MTPwebPage(new MTPDwebPage(_flags, _id, _url, _display_url, _type, _site_name, _title, _description, _photo, _embed_url, _embed_type, _embed_width, _embed_height, _duration, _author, _document));
}
inline MTPwebPage MTP_webPageExternal(MTPint _flags, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_title, const MTPstring &_description, const MTPstring &_thumb_url, const MTPstring &_content_url, MTPint _w, MTPint _h, MTPint _duration) {
return MTPwebPage(new MTPDwebPageExternal(_flags, _url, _display_url, _type, _title, _description, _thumb_url, _content_url, _w, _h, _duration));
inline MTPwebPage MTP_webPageExternal(MTPint _flags, const MTPstring &_url, const MTPstring &_display_url, const MTPstring &_type, const MTPstring &_title, const MTPstring &_description, const MTPstring &_thumb_url, const MTPstring &_content_url, MTPint _w, MTPint _h, const MTPstring &_embed_url, const MTPstring &_embed_type, MTPint _duration) {
return MTPwebPage(new MTPDwebPageExternal(_flags, _url, _display_url, _type, _title, _description, _thumb_url, _content_url, _w, _h, _embed_url, _embed_type, _duration));
}
inline MTPauthorization::MTPauthorization() : mtpDataOwner(new MTPDauthorization()) {

View File

@ -539,7 +539,7 @@ contactLinkContact#d502c2d0 = ContactLink;
webPageEmpty#eb1477e8 id:long = WebPage;
webPagePending#c586da1c id:long date:int = WebPage;
webPage#ca820ed7 flags:# id:long url:string display_url:string type:flags.0?string site_name:flags.1?string title:flags.2?string description:flags.3?string photo:flags.4?Photo embed_url:flags.5?string embed_type:flags.5?string embed_width:flags.6?int embed_height:flags.6?int duration:flags.7?int author:flags.8?string document:flags.9?Document = WebPage;
webPageExternal#cf73f207 flags:# url:string display_url:string type:flags.0?string title:flags.1?string description:flags.2?string thumb_url:flags.3?string content_url:flags.4?string w:flags.5?int h:flags.5?int duration:flags.6?int = WebPage;
webPageExternal#bb54b77 flags:# url:string display_url:string type:flags.0?string title:flags.1?string description:flags.2?string thumb_url:flags.3?string content_url:flags.4?string w:flags.5?int h:flags.5?int embed_url:flags.6?string embed_type:flags.6?string duration:flags.7?int = WebPage;
authorization#7bf2e6f6 hash:long flags:int device_model:string platform:string system_version:string api_id:int app_name:string app_version:string date_created:int date_active:int ip:string country:string region:string = Authorization;

File diff suppressed because it is too large Load Diff

View File

@ -110,6 +110,8 @@ public slots:
private:
MsgId complexMsgId(const HistoryItem *item) const;
bool itemMigrated(MsgId msgId) const;
ChannelId itemChannel(MsgId msgId) const;
MsgId itemMsgId(MsgId msgId) const;
@ -185,7 +187,7 @@ private:
FlatInput _search;
IconedButton _cancelSearch;
QVector<MsgId> _results;
int32 _itemsToBeLoaded;
int32 _cachedItemsToBeLoaded;
QTimer _searchTimer;
QString _searchQuery;
@ -211,6 +213,9 @@ private:
CachedLink *cachedLink(HistoryItem *item);
typedef QVector<LayoutItem*> Items;
Items _items;
// other
struct CachedItem {
CachedItem() : msgid(0), y(0), link(0) {
@ -223,7 +228,7 @@ private:
CachedLink *link;
};
typedef QVector<CachedItem> CachedItems;
CachedItems _items;
CachedItems _cachedItems;
int32 _width, _height, _minHeight, _addToY;

View File

@ -154,6 +154,13 @@ void PeerData::updateName(const QString &newName, const QString &newNameOrPhone,
}
}
const Text &BotCommand::descriptionText() const {
if (_descriptionText.isEmpty() && !_description.isEmpty()) {
_descriptionText.setText(st::mentionFont, _description, _textNameOptions);
}
return _descriptionText;
}
void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer as well
PhotoId newPhotoId = photoId;
ImagePtr newPhoto = photo;

View File

@ -301,7 +301,6 @@ private:
class BotCommand {
public:
BotCommand(const QString &command, const QString &description) : command(command), _description(description) {
}
QString command;
@ -314,12 +313,7 @@ public:
return false;
}
const Text &descriptionText() const {
if (_descriptionText.isEmpty() && !_description.isEmpty()) {
_descriptionText.setText(st::mentionFont, _description, _textNameOptions);
}
return _descriptionText;
}
const Text &descriptionText() const;
private:
QString _description;

View File

@ -1010,6 +1010,7 @@
<ClCompile Include="SourceFiles\lang.cpp" />
<ClCompile Include="SourceFiles\langloaderplain.cpp" />
<ClCompile Include="SourceFiles\layerwidget.cpp" />
<ClCompile Include="SourceFiles\layout.cpp" />
<ClCompile Include="SourceFiles\localimageloader.cpp" />
<ClCompile Include="SourceFiles\localstorage.cpp" />
<ClCompile Include="SourceFiles\logs.cpp" />
@ -1766,6 +1767,26 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -D_WITH_DEBUG -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\openssl\Release\include" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\SourceFiles" "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\..\..\Libraries\QtStatic\qtbase\include\QtCore\5.5.1\QtCore" "-I.\..\..\Libraries\QtStatic\qtbase\include\QtGui\5.5.1\QtGui" "-fstdafx.h" "-f../../SourceFiles/localstorage.h"</Command>
</CustomBuild>
<CustomBuild Include="SourceFiles\layout.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">
</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\logs.h" />
<CustomBuild Include="SourceFiles\mtproto\mtpConnection.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing mtpConnection.h...</Message>

View File

@ -894,6 +894,9 @@
<ClCompile Include="SourceFiles\mtproto\mtpAuthKey.cpp">
<Filter>mtproto</Filter>
</ClCompile>
<ClCompile Include="SourceFiles\layout.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SourceFiles\stdafx.h">
@ -1204,6 +1207,9 @@
<CustomBuild Include="SourceFiles\gui\popupmenu.h">
<Filter>gui</Filter>
</CustomBuild>
<CustomBuild Include="SourceFiles\layout.h">
<Filter>Source Files</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="SourceFiles\langs\lang_it.strings">