Improved files support in inline bot results.

This commit is contained in:
John Preston 2016-04-04 11:21:14 +04:00
parent 35785efa50
commit a2fc7f6915
7 changed files with 136 additions and 34 deletions

View File

@ -1798,10 +1798,10 @@ LayoutInlineItem *StickerPanInner::layoutPrepareInlineResult(InlineResult *resul
using Type = InlineResult::Type;
switch (result->type) {
case Type::Photo: layout = new LayoutInlinePhoto(result); break;
case Type::Audio:
case Type::File: layout = new LayoutInlineFile(result); break;
case Type::Video: layout = new LayoutInlineVideo(result); break;
case Type::Sticker: layout = new LayoutInlineSticker(result); break;
case Type::Audio:
case Type::File: //layout = new LayoutInlineFile(result); break;
case Type::Gif: layout = new LayoutInlineGif(result); break;
case Type::Article:
case Type::Contact:

View File

@ -1469,6 +1469,31 @@ QByteArray LayoutInlineAbstractFile::content_data() const {
return _result->data();
}
ImagePtr LayoutInlineAbstractFile::content_thumb() const {
if (DocumentData *document = getShownDocument()) {
if (!document->thumb->isNull()) {
return document->thumb;
}
}
if (_result->photo && !_result->photo->thumb->isNull()) {
return _result->photo->thumb;
}
return _result->thumb;
}
int LayoutInlineAbstractFile::content_duration() const {
if (_result->document) {
if (_result->document->duration() > 0) {
return _result->document->duration();
} else if (SongData *song = _result->document->song()) {
if (song->duration) {
return song->duration;
}
}
}
return _result->duration;
}
LayoutInlineGif::LayoutInlineGif(InlineResult *result) : LayoutInlineAbstractFile(result) {
}
@ -1955,19 +1980,19 @@ void LayoutInlinePhoto::content_forget() {
}
}
LayoutInlineVideo::LayoutInlineVideo(InlineResult *result) : LayoutInlineItem(result)
LayoutInlineVideo::LayoutInlineVideo(InlineResult *result) : LayoutInlineAbstractFile(result)
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip) {
if (!result->content_url.isEmpty()) {
_link = clickHandlerFromUrl(result->content_url);
}
if (int duration = getDuration()) {
if (int duration = content_duration()) {
_duration = formatDurationText(duration);
}
}
void LayoutInlineVideo::initDimensions() {
bool withThumb = !getThumb()->isNull();
bool withThumb = !content_thumb()->isNull();
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (withThumb ? (st::inlineThumbSize + st::inlineThumbSkip) : 0);
@ -1988,7 +2013,7 @@ void LayoutInlineVideo::initDimensions() {
void LayoutInlineVideo::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
int32 left = st::inlineThumbSize + st::inlineThumbSkip;
bool withThumb = !getThumb()->isNull();
bool withThumb = !content_thumb()->isNull();
if (withThumb) {
prepareThumb(st::inlineThumbSize, st::inlineThumbSize);
if (_thumb.isNull()) {
@ -2035,7 +2060,7 @@ void LayoutInlineVideo::getState(ClickHandlerPtr &link, HistoryCursorState &curs
}
void LayoutInlineVideo::prepareThumb(int32 width, int32 height) const {
ImagePtr thumb = getThumb();
ImagePtr thumb = content_thumb();
if (thumb->loaded()) {
if (_thumb.width() != width * cIntRetinaFactor() || _thumb.height() != height * cIntRetinaFactor()) {
int32 w = qMax(convertScale(thumb->width()), 1), h = qMax(convertScale(thumb->height()), 1);
@ -2057,6 +2082,88 @@ void LayoutInlineVideo::prepareThumb(int32 width, int32 height) const {
}
}
LayoutInlineFile::LayoutInlineFile(InlineResult *result) : LayoutInlineAbstractFile(result)
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip)
, _description(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::msgFileSize - st::inlineThumbSkip) {
}
void LayoutInlineFile::initDimensions() {
_maxw = st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft;
int32 textWidth = _maxw - (st::msgFileSize + st::inlineThumbSkip);
TextParseOptions titleOpts = { 0, _maxw, 2 * st::semiboldFont->height, Qt::LayoutDirectionAuto };
_title.setText(st::semiboldFont, textOneLine(_result->sendData->getLayoutTitle(_result)), titleOpts);
int32 titleHeight = qMin(_title.countHeight(_maxw), 2 * st::semiboldFont->height);
int32 descriptionLines = 1;
TextParseOptions descriptionOpts = { TextParseMultiline, _maxw, descriptionLines * st::normalFont->height, Qt::LayoutDirectionAuto };
_description.setText(st::normalFont, _result->sendData->getLayoutDescription(_result), descriptionOpts);
int32 descriptionHeight = qMin(_description.countHeight(_maxw), descriptionLines * st::normalFont->height);
_minh = st::msgFileSize;
_minh += st::inlineRowMargin * 2 + st::inlineRowBorder;
}
void LayoutInlineFile::paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const {
int32 left = st::msgFileSize + st::inlineThumbSkip;
QRect iconCircle = rtlrect(0, st::inlineRowMargin, st::msgFileSize, st::msgFileSize, _width);
p.setPen(Qt::NoPen);
//if (isThumbAnimation(ms)) {
// float64 over = _animation->a_thumbOver.current();
// p.setBrush(style::interpolate(outbg ? st::msgFileOutBg : st::msgFileInBg, outbg ? st::msgFileOutBgOver : st::msgFileInBgOver, over));
//} else {
bool over = ClickHandler::showAsActive(_send/*_data->loading() ? _cancell : _savel*/);
p.setBrush((over ? st::msgFileInBgOver : st::msgFileInBg));
//}
p.setRenderHint(QPainter::HighQualityAntialiasing);
p.drawEllipse(iconCircle);
p.setRenderHint(QPainter::HighQualityAntialiasing, false);
style::sprite icon;
if (bool showPause = false) {
icon = st::msgFileInPause;
//} else if (radial || _data->loading()) {
// icon = st::msgFileInCancel;
//} else if (loaded) {
// if (_data->song() || _data->voice()) {
// icon = outbg ? (selected ? st::msgFileOutPlaySelected : st::msgFileOutPlay) : (selected ? st::msgFileInPlaySelected : st::msgFileInPlay);
// } else if (_data->isImage()) {
// icon = outbg ? (selected ? st::msgFileOutImageSelected : st::msgFileOutImage) : (selected ? st::msgFileInImageSelected : st::msgFileInImage);
// } else {
// icon = outbg ? (selected ? st::msgFileOutFileSelected : st::msgFileOutFile) : (selected ? st::msgFileInFileSelected : st::msgFileInFile);
// }
} else {
icon = st::msgFileInDownload;
}
p.drawSpriteCenter(iconCircle, icon);
p.setPen(st::black);
_title.drawLeftElided(p, left, st::inlineRowMargin, _width - left, _width, 2);
int32 titleHeight = qMin(_title.countHeight(_width - left), st::semiboldFont->height * 2);
p.setPen(st::inlineDescriptionFg);
int32 descriptionLines = 1;
_description.drawLeftElided(p, left, st::inlineRowMargin + titleHeight, _width - left, _width, descriptionLines);
const InlinePaintContext *ctx = context->toInlinePaintContext();
t_assert(ctx != nullptr);
if (!ctx->lastRow) {
p.fillRect(rtlrect(left, _height - st::inlineRowBorder, _width - left, st::inlineRowBorder, _width), st::inlineRowBorderFg);
}
}
void LayoutInlineFile::getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const {
if (x >= 0 && x < st::msgFileSize && y >= st::inlineRowMargin && y < st::inlineRowMargin + st::msgFileSize) {
return;
}
if (x >= st::msgFileSize + st::inlineThumbSkip && x < _width && y >= 0 && y < _height) {
link = _send;
return;
}
}
LayoutInlineArticle::LayoutInlineArticle(InlineResult *result, bool withThumb) : LayoutInlineItem(result)
, _withThumb(withThumb)
, _title(st::emojiPanWidth - st::emojiScroll.width - st::inlineResultsLeft - st::inlineThumbSize - st::inlineThumbSkip)

View File

@ -552,7 +552,8 @@ protected:
void content_forget();
FileLocation content_location() const;
QByteArray content_data() const;
ImagePtr content_thumb() const;
int content_duration() const;
};
class DeleteSavedGifClickHandler : public LeftButtonClickHandler {
@ -709,7 +710,7 @@ private:
};
class LayoutInlineVideo : public LayoutInlineItem {
class LayoutInlineVideo : public LayoutInlineAbstractFile {
public:
LayoutInlineVideo(InlineResult *result);
@ -720,20 +721,6 @@ public:
private:
ImagePtr getThumb() const {
if (_result->document && !_result->document->thumb->isNull()) {
return _result->document->thumb;
} else if (_result->photo && !_result->photo->thumb->isNull()) {
return _result->photo->thumb;
}
return _result->thumb;
}
int getDuration() const {
if (_result->document && _result->document->duration() > 0) {
return _result->document->duration();
}
return _result->duration;
}
ClickHandlerPtr _link;
mutable QPixmap _thumb;
@ -750,19 +737,13 @@ public:
LayoutInlineFile(InlineResult *result);
void initDimensions() override;
int32 resizeGetHeight(int32 width) override;
void paint(Painter &p, const QRect &clip, uint32 selection, const PaintContext *context) const override;
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int32 x, int32 y) const override;
private:
mutable QPixmap _thumb;
Text _title, _description;
QString _letter, _urlText;
int32 _urlWidth;
void prepareThumb(int32 width, int32 height) const;
};

View File

@ -1529,11 +1529,15 @@ InlineResultSendData::SentMTPMessageFields InlineResultSendFile::getSentMessageF
uint64 docId = rand_value<uint64>();
QVector<MTPDocumentAttribute> attributes;
int duration = getSentDuration(owner);
QSize dimensions = getSentDimensions(owner);
using Type = InlineResult::Type;
if (owner->type == Type::Gif) {
attributes.push_back(MTP_documentAttributeFilename(MTP_string((owner->content_type == qstr("video/mp4") ? "animation.gif.mp4" : "animation.gif"))));
attributes.push_back(MTP_documentAttributeAnimated());
attributes.push_back(MTP_documentAttributeVideo(MTP_int(owner->duration), MTP_int(owner->width), MTP_int(owner->height)));
attributes.push_back(MTP_documentAttributeVideo(MTP_int(duration), MTP_int(dimensions.width()), MTP_int(dimensions.height())));
} else if (owner->type == Type::Video) {
attributes.push_back(MTP_documentAttributeVideo(MTP_int(duration), MTP_int(dimensions.width()), MTP_int(dimensions.height())));
}
MTPDocument document = MTP_document(MTP_long(docId), MTP_long(0), MTP_int(unixtime()), MTP_string(owner->content_type), MTP_int(owner->data().size()), thumbSize, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
if (tw > 0 && th > 0) {
@ -1546,6 +1550,13 @@ InlineResultSendData::SentMTPMessageFields InlineResultSendFile::getSentMessageF
return result;
}
int InlineResultSendFile::getSentDuration(InlineResult *owner) const {
return (_document && _document->duration()) ? _document->duration() : owner->duration;
}
QSize InlineResultSendFile::getSentDimensions(InlineResult *owner) const {
return (!_document || _document->dimensions.isEmpty()) ? QSize(owner->width, owner->height) : _document->dimensions;
}
void InlineResult::automaticLoadGif() {
if (loaded() || type != Type::Gif || (content_type != qstr("video/mp4") && content_type != "image/gif")) return;

View File

@ -1440,6 +1440,9 @@ private:
DocumentData *_document;
QString _url, _caption;
int getSentDuration(InlineResult *owner) const;
QSize getSentDimensions(InlineResult *owner) const;
};
class InlineResult {

View File

@ -1203,6 +1203,7 @@
<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" "-fstdafx.h" "-f../../SourceFiles/basic_types.h" -DAL_LIBTYPE_STATIC -DUNICODE -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.\..\..\Libraries\breakpad\src" "-I.\ThirdParty\minizip" "-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"</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\gui\style.h" />
<ClInclude Include="SourceFiles\mtproto\auth_key.h" />
<CustomBuild Include="SourceFiles\mtproto\connection.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Deploy|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
@ -2203,7 +2204,6 @@
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Command>
</CustomBuild>
<ClInclude Include="SourceFiles\style.h" />
<CustomBuild Include="SourceFiles\sysbuttons.h">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Moc%27ing sysbuttons.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>

View File

@ -986,9 +986,6 @@
<ClInclude Include="GeneratedFiles\style_classes.h">
<Filter>Generated Files</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\style.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\countries.h">
<Filter>Source Files</Filter>
</ClInclude>
@ -1067,6 +1064,9 @@
<ClInclude Include="SourceFiles\mtproto\scheme_auto.h">
<Filter>mtproto</Filter>
</ClInclude>
<ClInclude Include="SourceFiles\gui\style.h">
<Filter>gui</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="SourceFiles\application.h">