mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-17 20:43:58 +02:00
Currently the build without implicitly included precompiled header is not supported anyway (because Qt MOC source files do not include stdafx.h, they include plain headers). So when we decide to support building without implicitly included precompiled headers we'll have to fix all the headers anyway.
664 lines
24 KiB
C++
664 lines
24 KiB
C++
/*
|
|
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-2017 John Preston, https://desktop.telegram.org
|
|
*/
|
|
#include "boxes/send_files_box.h"
|
|
|
|
#include "lang.h"
|
|
#include "localstorage.h"
|
|
#include "mainwidget.h"
|
|
#include "history/history_media_types.h"
|
|
#include "core/file_utilities.h"
|
|
#include "ui/widgets/checkbox.h"
|
|
#include "ui/widgets/buttons.h"
|
|
#include "ui/widgets/input_fields.h"
|
|
#include "styles/style_history.h"
|
|
#include "styles/style_boxes.h"
|
|
|
|
namespace {
|
|
|
|
constexpr auto kMinPreviewWidth = 20;
|
|
|
|
} // namespace
|
|
|
|
SendFilesBox::SendFilesBox(QWidget*, const QString &filepath, QImage image, CompressConfirm compressed, bool animated)
|
|
: _files(filepath)
|
|
, _image(image)
|
|
, _compressConfirm(compressed)
|
|
, _animated(image.isNull() ? false : animated)
|
|
, _caption(this, st::confirmCaptionArea, lang(lng_photo_caption)) {
|
|
if (!image.isNull()) {
|
|
if (!_animated && _compressConfirm == CompressConfirm::None) {
|
|
auto originalWidth = image.width();
|
|
auto originalHeight = image.height();
|
|
auto thumbWidth = st::msgFileThumbSize;
|
|
if (originalWidth > originalHeight) {
|
|
thumbWidth = (originalWidth * st::msgFileThumbSize) / originalHeight;
|
|
}
|
|
auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomRight;
|
|
_fileThumb = Images::pixmap(image, thumbWidth * cIntRetinaFactor(), 0, options, st::msgFileThumbSize, st::msgFileThumbSize);
|
|
} else {
|
|
auto maxW = 0;
|
|
auto maxH = 0;
|
|
if (_animated) {
|
|
auto limitW = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
|
auto limitH = st::confirmMaxHeight;
|
|
maxW = qMax(image.width(), 1);
|
|
maxH = qMax(image.height(), 1);
|
|
if (maxW * limitH > maxH * limitW) {
|
|
if (maxW < limitW) {
|
|
maxH = maxH * limitW / maxW;
|
|
maxW = limitW;
|
|
}
|
|
} else {
|
|
if (maxH < limitH) {
|
|
maxW = maxW * limitH / maxH;
|
|
maxH = limitH;
|
|
}
|
|
}
|
|
image = Images::prepare(image, maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth | Images::Option::Blurred, maxW, maxH);
|
|
}
|
|
auto originalWidth = image.width();
|
|
auto originalHeight = image.height();
|
|
if (!originalWidth || !originalHeight) {
|
|
originalWidth = originalHeight = 1;
|
|
}
|
|
_previewWidth = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
|
if (image.width() < _previewWidth) {
|
|
_previewWidth = qMax(image.width(), kMinPreviewWidth);
|
|
}
|
|
auto maxthumbh = qMin(qRound(1.5 * _previewWidth), st::confirmMaxHeight);
|
|
_previewHeight = qRound(originalHeight * float64(_previewWidth) / originalWidth);
|
|
if (_previewHeight > maxthumbh) {
|
|
_previewWidth = qRound(_previewWidth * float64(maxthumbh) / _previewHeight);
|
|
accumulate_max(_previewWidth, kMinPreviewWidth);
|
|
_previewHeight = maxthumbh;
|
|
}
|
|
_previewLeft = (st::boxWideWidth - _previewWidth) / 2;
|
|
|
|
image = std::move(image).scaled(_previewWidth * cIntRetinaFactor(), _previewHeight * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
image = Images::prepareOpaque(std::move(image));
|
|
_preview = App::pixmapFromImageInPlace(std::move(image));
|
|
_preview.setDevicePixelRatio(cRetinaFactor());
|
|
}
|
|
}
|
|
if (_preview.isNull()) {
|
|
if (filepath.isEmpty()) {
|
|
auto filename = filedialogDefaultName(qsl("image"), qsl(".png"), QString(), true);
|
|
_nameText.setText(st::semiboldTextStyle, filename, _textNameOptions);
|
|
_statusText = qsl("%1x%2").arg(_image.width()).arg(_image.height());
|
|
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
|
|
_fileIsImage = true;
|
|
} else {
|
|
auto fileinfo = QFileInfo(filepath);
|
|
auto filename = fileinfo.fileName();
|
|
_nameText.setText(st::semiboldTextStyle, filename, _textNameOptions);
|
|
_statusText = formatSizeText(fileinfo.size());
|
|
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
|
|
_fileIsImage = fileIsImage(filename, mimeTypeForFile(fileinfo).name());
|
|
}
|
|
}
|
|
}
|
|
|
|
SendFilesBox::SendFilesBox(QWidget*, const QStringList &files, CompressConfirm compressed)
|
|
: _files(files)
|
|
, _compressConfirm(compressed)
|
|
, _caption(this, st::confirmCaptionArea, lang(lng_photos_comment)) {
|
|
}
|
|
|
|
SendFilesBox::SendFilesBox(QWidget*, const QString &phone, const QString &firstname, const QString &lastname)
|
|
: _contactPhone(phone)
|
|
, _contactFirstName(firstname)
|
|
, _contactLastName(lastname) {
|
|
auto name = lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName);
|
|
_nameText.setText(st::semiboldTextStyle, name, _textNameOptions);
|
|
_statusText = _contactPhone;
|
|
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
|
|
_contactPhotoEmpty.set(0, name);
|
|
}
|
|
|
|
void SendFilesBox::prepare() {
|
|
if (_files.size() > 1) {
|
|
updateTitleText();
|
|
}
|
|
|
|
_send = addButton(lang(lng_send_button), [this] { onSend(); });
|
|
addButton(lang(lng_cancel), [this] { closeBox(); });
|
|
|
|
if (_compressConfirm != CompressConfirm::None) {
|
|
auto compressed = (_compressConfirm == CompressConfirm::Auto) ? cCompressPastedImage() : (_compressConfirm == CompressConfirm::Yes);
|
|
auto text = lng_send_images_compress(lt_count, _files.size());
|
|
_compressed.create(this, text, compressed, st::defaultBoxCheckbox);
|
|
connect(_compressed, SIGNAL(changed()), this, SLOT(onCompressedChange()));
|
|
}
|
|
if (_caption) {
|
|
_caption->setMaxLength(MaxPhotoCaption);
|
|
_caption->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both);
|
|
connect(_caption, SIGNAL(resized()), this, SLOT(onCaptionResized()));
|
|
connect(_caption, SIGNAL(submitted(bool)), this, SLOT(onSend(bool)));
|
|
connect(_caption, SIGNAL(cancelled()), this, SLOT(onClose()));
|
|
}
|
|
_send->setText(getSendButtonText());
|
|
updateButtonsGeometry();
|
|
updateBoxSize();
|
|
}
|
|
|
|
QString SendFilesBox::getSendButtonText() const {
|
|
if (!_contactPhone.isEmpty()) {
|
|
return lang(lng_send_button);
|
|
} else if (_compressed && _compressed->checked()) {
|
|
return lng_send_photos(lt_count, _files.size());
|
|
}
|
|
return lng_send_files(lt_count, _files.size());
|
|
}
|
|
|
|
void SendFilesBox::onCompressedChange() {
|
|
setInnerFocus();
|
|
_send->setText(getSendButtonText());
|
|
updateButtonsGeometry();
|
|
updateControlsGeometry();
|
|
}
|
|
|
|
void SendFilesBox::onCaptionResized() {
|
|
updateBoxSize();
|
|
updateControlsGeometry();
|
|
update();
|
|
}
|
|
|
|
void SendFilesBox::updateTitleText() {
|
|
_titleText = (_compressConfirm == CompressConfirm::None) ? lng_send_files_selected(lt_count, _files.size()) : lng_send_images_selected(lt_count, _files.size());
|
|
update();
|
|
}
|
|
|
|
void SendFilesBox::updateBoxSize() {
|
|
auto newHeight = _titleText.isEmpty() ? 0 : st::boxTitleHeight;
|
|
if (!_preview.isNull()) {
|
|
newHeight += st::boxPhotoPadding.top() + _previewHeight;
|
|
} else if (!_fileThumb.isNull()) {
|
|
newHeight += st::boxPhotoPadding.top() + st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom();
|
|
} else if (_files.size() > 1) {
|
|
newHeight += 0;
|
|
} else {
|
|
newHeight += st::boxPhotoPadding.top() + st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom();
|
|
}
|
|
if (_compressed) {
|
|
newHeight += st::boxPhotoCompressedSkip + _compressed->heightNoMargins();
|
|
}
|
|
if (_caption) {
|
|
newHeight += st::boxPhotoCaptionSkip + _caption->height();
|
|
}
|
|
setDimensions(st::boxWideWidth, newHeight);
|
|
}
|
|
|
|
void SendFilesBox::keyPressEvent(QKeyEvent *e) {
|
|
if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) {
|
|
onSend((e->modifiers().testFlag(Qt::ControlModifier) || e->modifiers().testFlag(Qt::MetaModifier)) && e->modifiers().testFlag(Qt::ShiftModifier));
|
|
} else {
|
|
BoxContent::keyPressEvent(e);
|
|
}
|
|
}
|
|
|
|
void SendFilesBox::paintEvent(QPaintEvent *e) {
|
|
BoxContent::paintEvent(e);
|
|
|
|
Painter p(this);
|
|
|
|
if (!_titleText.isEmpty()) {
|
|
p.setFont(st::boxPhotoTitleFont);
|
|
p.setPen(st::boxTitleFg);
|
|
p.drawTextLeft(st::boxPhotoTitlePosition.x(), st::boxPhotoTitlePosition.y(), width(), _titleText);
|
|
}
|
|
|
|
if (!_preview.isNull()) {
|
|
if (_previewLeft > st::boxPhotoPadding.left()) {
|
|
p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _previewLeft - st::boxPhotoPadding.left(), _previewHeight, st::confirmBg);
|
|
}
|
|
if (_previewLeft + _previewWidth < width() - st::boxPhotoPadding.right()) {
|
|
p.fillRect(_previewLeft + _previewWidth, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _previewLeft - _previewWidth, _previewHeight, st::confirmBg);
|
|
}
|
|
p.drawPixmap(_previewLeft, st::boxPhotoPadding.top(), _preview);
|
|
if (_animated) {
|
|
auto inner = QRect(_previewLeft + (_previewWidth - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (_previewHeight - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(st::msgDateImgBg);
|
|
|
|
{
|
|
PainterHighQualityEnabler hq(p);
|
|
p.drawEllipse(inner);
|
|
}
|
|
|
|
auto icon = &st::historyFileInPlay;
|
|
icon->paintInCenter(p, inner);
|
|
}
|
|
} else if (_files.size() < 2) {
|
|
auto w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
|
auto h = _fileThumb.isNull() ? (st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom()) : (st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom());
|
|
auto nameleft = 0, nametop = 0, nameright = 0, statustop = 0, linktop = 0;
|
|
if (_fileThumb.isNull()) {
|
|
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
|
nametop = st::msgFileNameTop;
|
|
nameright = st::msgFilePadding.left();
|
|
statustop = st::msgFileStatusTop;
|
|
} else {
|
|
nameleft = st::msgFileThumbPadding.left() + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
|
nametop = st::msgFileThumbNameTop;
|
|
nameright = st::msgFileThumbPadding.left();
|
|
statustop = st::msgFileThumbStatusTop;
|
|
linktop = st::msgFileThumbLinkTop;
|
|
}
|
|
auto namewidth = w - nameleft - (_fileThumb.isNull() ? st::msgFilePadding.left() : st::msgFileThumbPadding.left());
|
|
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
|
|
|
App::roundRect(p, x, y, w, h, st::msgOutBg, MessageOutCorners, &st::msgOutShadow);
|
|
|
|
if (_fileThumb.isNull()) {
|
|
if (_contactPhone.isNull()) {
|
|
QRect inner(rtlrect(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), st::msgFileSize, st::msgFileSize, width()));
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(st::msgFileOutBg);
|
|
|
|
{
|
|
PainterHighQualityEnabler hq(p);
|
|
p.drawEllipse(inner);
|
|
}
|
|
|
|
auto &icon = _fileIsImage ? st::historyFileOutImage : st::historyFileOutDocument;
|
|
icon.paintInCenter(p, inner);
|
|
} else {
|
|
_contactPhotoEmpty.paint(p, x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), st::msgFileSize);
|
|
}
|
|
} else {
|
|
QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
|
p.drawPixmap(rthumb.topLeft(), _fileThumb);
|
|
}
|
|
p.setFont(st::semiboldFont);
|
|
p.setPen(st::historyFileNameOutFg);
|
|
_nameText.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width());
|
|
|
|
auto &status = st::mediaOutFg;
|
|
p.setFont(st::normalFont);
|
|
p.setPen(status);
|
|
p.drawTextLeft(x + nameleft, y + statustop, width(), _statusText);
|
|
}
|
|
}
|
|
|
|
void SendFilesBox::resizeEvent(QResizeEvent *e) {
|
|
BoxContent::resizeEvent(e);
|
|
updateControlsGeometry();
|
|
}
|
|
|
|
void SendFilesBox::updateControlsGeometry() {
|
|
auto bottom = height();
|
|
if (_caption) {
|
|
_caption->resize(st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), _caption->height());
|
|
_caption->moveToLeft(st::boxPhotoPadding.left(), bottom - _caption->height());
|
|
bottom -= st::boxPhotoCaptionSkip + _caption->height();
|
|
}
|
|
if (_compressed) {
|
|
_compressed->moveToLeft(st::boxPhotoPadding.left(), bottom - _compressed->heightNoMargins());
|
|
bottom -= st::boxPhotoCompressedSkip + _compressed->heightNoMargins();
|
|
}
|
|
}
|
|
|
|
void SendFilesBox::setInnerFocus() {
|
|
if (!_caption || _caption->isHidden()) {
|
|
setFocus();
|
|
} else {
|
|
_caption->setFocusFast();
|
|
}
|
|
}
|
|
|
|
void SendFilesBox::onSend(bool ctrlShiftEnter) {
|
|
if (_compressed && _compressConfirm == CompressConfirm::Auto && _compressed->checked() != cCompressPastedImage()) {
|
|
cSetCompressPastedImage(_compressed->checked());
|
|
Local::writeUserSettings();
|
|
}
|
|
_confirmed = true;
|
|
if (_confirmedCallback) {
|
|
auto compressed = _compressed ? _compressed->checked() : false;
|
|
auto caption = _caption ? prepareText(_caption->getLastText(), true) : QString();
|
|
_confirmedCallback(_files, compressed, caption, ctrlShiftEnter);
|
|
}
|
|
closeBox();
|
|
}
|
|
|
|
void SendFilesBox::closeHook() {
|
|
if (!_confirmed && _cancelledCallback) {
|
|
_cancelledCallback();
|
|
}
|
|
}
|
|
|
|
EditCaptionBox::EditCaptionBox(QWidget*, HistoryItem *msg)
|
|
: _msgId(msg->fullId()) {
|
|
QSize dimensions;
|
|
ImagePtr image;
|
|
QString caption;
|
|
DocumentData *doc = 0;
|
|
if (HistoryMedia *media = msg->getMedia()) {
|
|
HistoryMediaType t = media->type();
|
|
switch (t) {
|
|
case MediaTypeGif: {
|
|
_animated = true;
|
|
doc = static_cast<HistoryGif*>(media)->getDocument();
|
|
dimensions = doc->dimensions;
|
|
image = doc->thumb;
|
|
} break;
|
|
|
|
case MediaTypePhoto: {
|
|
_photo = true;
|
|
PhotoData *photo = static_cast<HistoryPhoto*>(media)->photo();
|
|
dimensions = QSize(photo->full->width(), photo->full->height());
|
|
image = photo->full;
|
|
} break;
|
|
|
|
case MediaTypeVideo: {
|
|
_animated = true;
|
|
doc = static_cast<HistoryVideo*>(media)->getDocument();
|
|
dimensions = doc->dimensions;
|
|
image = doc->thumb;
|
|
} break;
|
|
|
|
case MediaTypeFile:
|
|
case MediaTypeMusicFile:
|
|
case MediaTypeVoiceFile: {
|
|
_doc = true;
|
|
doc = static_cast<HistoryDocument*>(media)->getDocument();
|
|
image = doc->thumb;
|
|
} break;
|
|
}
|
|
caption = media->getCaption().text;
|
|
}
|
|
if ((!_animated && (dimensions.isEmpty() || doc)) || image->isNull()) {
|
|
_animated = false;
|
|
if (image->isNull()) {
|
|
_thumbw = 0;
|
|
} else {
|
|
int32 tw = image->width(), th = image->height();
|
|
if (tw > th) {
|
|
_thumbw = (tw * st::msgFileThumbSize) / th;
|
|
} else {
|
|
_thumbw = st::msgFileThumbSize;
|
|
}
|
|
auto options = Images::Option::Smooth | Images::Option::RoundedSmall | Images::Option::RoundedTopLeft | Images::Option::RoundedTopRight | Images::Option::RoundedBottomLeft | Images::Option::RoundedBottomRight;
|
|
_thumb = Images::pixmap(image->pix().toImage(), _thumbw * cIntRetinaFactor(), 0, options, st::msgFileThumbSize, st::msgFileThumbSize);
|
|
}
|
|
|
|
if (doc) {
|
|
if (doc->voice()) {
|
|
_name.setText(st::semiboldTextStyle, lang(lng_media_audio), _textNameOptions);
|
|
} else {
|
|
_name.setText(st::semiboldTextStyle, documentName(doc), _textNameOptions);
|
|
}
|
|
_status = formatSizeText(doc->size);
|
|
_statusw = qMax(_name.maxWidth(), st::normalFont->width(_status));
|
|
_isImage = doc->isImage();
|
|
}
|
|
} else {
|
|
int32 maxW = 0, maxH = 0;
|
|
if (_animated) {
|
|
int32 limitW = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
|
int32 limitH = st::confirmMaxHeight;
|
|
maxW = qMax(dimensions.width(), 1);
|
|
maxH = qMax(dimensions.height(), 1);
|
|
if (maxW * limitH > maxH * limitW) {
|
|
if (maxW < limitW) {
|
|
maxH = maxH * limitW / maxW;
|
|
maxW = limitW;
|
|
}
|
|
} else {
|
|
if (maxH < limitH) {
|
|
maxW = maxW * limitH / maxH;
|
|
maxH = limitH;
|
|
}
|
|
}
|
|
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth | Images::Option::Blurred, maxW, maxH);
|
|
} else {
|
|
maxW = dimensions.width();
|
|
maxH = dimensions.height();
|
|
_thumb = image->pixNoCache(maxW * cIntRetinaFactor(), maxH * cIntRetinaFactor(), Images::Option::Smooth, maxW, maxH);
|
|
}
|
|
int32 tw = _thumb.width(), th = _thumb.height();
|
|
if (!tw || !th) {
|
|
tw = th = 1;
|
|
}
|
|
_thumbw = st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
|
if (_thumb.width() < _thumbw) {
|
|
_thumbw = (_thumb.width() > 20) ? _thumb.width() : 20;
|
|
}
|
|
int32 maxthumbh = qMin(qRound(1.5 * _thumbw), int(st::confirmMaxHeight));
|
|
_thumbh = qRound(th * float64(_thumbw) / tw);
|
|
if (_thumbh > maxthumbh) {
|
|
_thumbw = qRound(_thumbw * float64(maxthumbh) / _thumbh);
|
|
_thumbh = maxthumbh;
|
|
if (_thumbw < 10) {
|
|
_thumbw = 10;
|
|
}
|
|
}
|
|
_thumbx = (st::boxWideWidth - _thumbw) / 2;
|
|
|
|
_thumb = App::pixmapFromImageInPlace(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
|
_thumb.setDevicePixelRatio(cRetinaFactor());
|
|
}
|
|
if (_animated || _photo || _doc) {
|
|
_field.create(this, st::confirmCaptionArea, lang(lng_photo_caption), caption);
|
|
_field->setMaxLength(MaxPhotoCaption);
|
|
_field->setCtrlEnterSubmit(Ui::CtrlEnterSubmit::Both);
|
|
} else {
|
|
auto original = msg->originalText();
|
|
auto text = textApplyEntities(original.text, original.entities);
|
|
_field.create(this, st::editTextArea, lang(lng_photo_caption), text);
|
|
// _field->setMaxLength(MaxMessageSize); // entities can make text in input field larger but still valid
|
|
_field->setCtrlEnterSubmit(cCtrlEnter() ? Ui::CtrlEnterSubmit::CtrlEnter : Ui::CtrlEnterSubmit::Enter);
|
|
}
|
|
}
|
|
|
|
bool EditCaptionBox::canEdit(HistoryItem *message) {
|
|
if (auto media = message->getMedia()) {
|
|
switch (media->type()) {
|
|
case MediaTypeGif:
|
|
case MediaTypePhoto:
|
|
case MediaTypeVideo:
|
|
case MediaTypeFile:
|
|
case MediaTypeMusicFile:
|
|
case MediaTypeVoiceFile: return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void EditCaptionBox::prepare() {
|
|
addButton(lang(lng_settings_save), [this] { onSave(); });
|
|
addButton(lang(lng_cancel), [this] { closeBox(); });
|
|
|
|
updateBoxSize();
|
|
connect(_field, SIGNAL(submitted(bool)), this, SLOT(onSave(bool)));
|
|
connect(_field, SIGNAL(cancelled()), this, SLOT(onClose()));
|
|
connect(_field, SIGNAL(resized()), this, SLOT(onCaptionResized()));
|
|
|
|
auto cursor = _field->textCursor();
|
|
cursor.movePosition(QTextCursor::End);
|
|
_field->setTextCursor(cursor);
|
|
}
|
|
|
|
void EditCaptionBox::onCaptionResized() {
|
|
updateBoxSize();
|
|
resizeEvent(0);
|
|
update();
|
|
}
|
|
|
|
void EditCaptionBox::updateBoxSize() {
|
|
auto newHeight = st::boxPhotoPadding.top() + st::boxPhotoCaptionSkip + _field->height() + st::normalFont->height;
|
|
if (_photo || _animated) {
|
|
newHeight += _thumbh;
|
|
} else if (_thumbw) {
|
|
newHeight += 0 + st::msgFileThumbSize + 0;
|
|
} else if (_doc) {
|
|
newHeight += 0 + st::msgFileSize + 0;
|
|
} else {
|
|
newHeight += st::boxTitleFont->height;
|
|
}
|
|
setDimensions(st::boxWideWidth, newHeight);
|
|
}
|
|
|
|
void EditCaptionBox::paintEvent(QPaintEvent *e) {
|
|
BoxContent::paintEvent(e);
|
|
|
|
Painter p(this);
|
|
|
|
if (_photo || _animated) {
|
|
if (_thumbx > st::boxPhotoPadding.left()) {
|
|
p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _thumbx - st::boxPhotoPadding.left(), _thumbh, st::confirmBg);
|
|
}
|
|
if (_thumbx + _thumbw < width() - st::boxPhotoPadding.right()) {
|
|
p.fillRect(_thumbx + _thumbw, st::boxPhotoPadding.top(), width() - st::boxPhotoPadding.right() - _thumbx - _thumbw, _thumbh, st::confirmBg);
|
|
}
|
|
p.drawPixmap(_thumbx, st::boxPhotoPadding.top(), _thumb);
|
|
if (_animated) {
|
|
QRect inner(_thumbx + (_thumbw - st::msgFileSize) / 2, st::boxPhotoPadding.top() + (_thumbh - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(st::msgDateImgBg);
|
|
|
|
{
|
|
PainterHighQualityEnabler hq(p);
|
|
p.drawEllipse(inner);
|
|
}
|
|
|
|
auto icon = &st::historyFileInPlay;
|
|
icon->paintInCenter(p, inner);
|
|
}
|
|
} else if (_doc) {
|
|
int32 w = width() - st::boxPhotoPadding.left() - st::boxPhotoPadding.right();
|
|
int32 h = _thumbw ? (0 + st::msgFileThumbSize + 0) : (0 + st::msgFileSize + 0);
|
|
int32 nameleft = 0, nametop = 0, nameright = 0, statustop = 0;
|
|
if (_thumbw) {
|
|
nameleft = 0 + st::msgFileThumbSize + st::msgFileThumbPadding.right();
|
|
nametop = st::msgFileThumbNameTop - st::msgFileThumbPadding.top();
|
|
nameright = 0;
|
|
statustop = st::msgFileThumbStatusTop - st::msgFileThumbPadding.top();
|
|
} else {
|
|
nameleft = 0 + st::msgFileSize + st::msgFilePadding.right();
|
|
nametop = st::msgFileNameTop - st::msgFilePadding.top();
|
|
nameright = 0;
|
|
statustop = st::msgFileStatusTop - st::msgFilePadding.top();
|
|
}
|
|
int32 namewidth = w - nameleft - 0;
|
|
if (namewidth > _statusw) {
|
|
//w -= (namewidth - _statusw);
|
|
//namewidth = _statusw;
|
|
}
|
|
int32 x = (width() - w) / 2, y = st::boxPhotoPadding.top();
|
|
|
|
// App::roundRect(p, x, y, w, h, st::msgInBg, MessageInCorners, &st::msgInShadow);
|
|
|
|
if (_thumbw) {
|
|
QRect rthumb(rtlrect(x + 0, y + 0, st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
|
p.drawPixmap(rthumb.topLeft(), _thumb);
|
|
} else {
|
|
QRect inner(rtlrect(x + 0, y + 0, st::msgFileSize, st::msgFileSize, width()));
|
|
p.setPen(Qt::NoPen);
|
|
p.setBrush(st::msgFileInBg);
|
|
|
|
{
|
|
PainterHighQualityEnabler hq(p);
|
|
p.drawEllipse(inner);
|
|
}
|
|
|
|
auto icon = &(_isImage ? st::historyFileInImage : st::historyFileInDocument);
|
|
icon->paintInCenter(p, inner);
|
|
}
|
|
p.setFont(st::semiboldFont);
|
|
p.setPen(st::historyFileNameInFg);
|
|
_name.drawLeftElided(p, x + nameleft, y + nametop, namewidth, width());
|
|
|
|
auto &status = st::mediaInFg;
|
|
p.setFont(st::normalFont);
|
|
p.setPen(status);
|
|
p.drawTextLeft(x + nameleft, y + statustop, width(), _status);
|
|
} else {
|
|
p.setFont(st::boxTitleFont);
|
|
p.setPen(st::boxTextFg);
|
|
p.drawTextLeft(_field->x(), st::boxPhotoPadding.top(), width(), lang(lng_edit_message));
|
|
}
|
|
|
|
if (!_error.isEmpty()) {
|
|
p.setFont(st::normalFont);
|
|
p.setPen(st::boxTextFgError);
|
|
p.drawTextLeft(_field->x(), _field->y() + _field->height() + (st::boxButtonPadding.top() / 2), width(), _error);
|
|
}
|
|
}
|
|
|
|
void EditCaptionBox::resizeEvent(QResizeEvent *e) {
|
|
BoxContent::resizeEvent(e);
|
|
_field->resize(st::boxWideWidth - st::boxPhotoPadding.left() - st::boxPhotoPadding.right(), _field->height());
|
|
_field->moveToLeft(st::boxPhotoPadding.left(), height() - st::normalFont->height - _field->height());
|
|
}
|
|
|
|
void EditCaptionBox::setInnerFocus() {
|
|
_field->setFocusFast();
|
|
}
|
|
|
|
void EditCaptionBox::onSave(bool ctrlShiftEnter) {
|
|
if (_saveRequestId) return;
|
|
|
|
HistoryItem *item = App::histItemById(_msgId);
|
|
if (!item) {
|
|
_error = lang(lng_edit_deleted);
|
|
update();
|
|
return;
|
|
}
|
|
|
|
MTPmessages_EditMessage::Flags flags = MTPmessages_EditMessage::Flag::f_message;
|
|
if (_previewCancelled) {
|
|
flags |= MTPmessages_EditMessage::Flag::f_no_webpage;
|
|
}
|
|
MTPVector<MTPMessageEntity> sentEntities;
|
|
if (!sentEntities.c_vector().v.isEmpty()) {
|
|
flags |= MTPmessages_EditMessage::Flag::f_entities;
|
|
}
|
|
auto text = prepareText(_field->getLastText(), true);
|
|
_saveRequestId = MTP::send(MTPmessages_EditMessage(MTP_flags(flags), item->history()->peer->input, MTP_int(item->id), MTP_string(text), MTPnullMarkup, sentEntities), rpcDone(&EditCaptionBox::saveDone), rpcFail(&EditCaptionBox::saveFail));
|
|
}
|
|
|
|
void EditCaptionBox::saveDone(const MTPUpdates &updates) {
|
|
_saveRequestId = 0;
|
|
closeBox();
|
|
if (App::main()) {
|
|
App::main()->sentUpdatesReceived(updates);
|
|
}
|
|
}
|
|
|
|
bool EditCaptionBox::saveFail(const RPCError &error) {
|
|
if (MTP::isDefaultHandledError(error)) return false;
|
|
|
|
_saveRequestId = 0;
|
|
QString err = error.type();
|
|
if (err == qstr("MESSAGE_ID_INVALID") || err == qstr("CHAT_ADMIN_REQUIRED") || err == qstr("MESSAGE_EDIT_TIME_EXPIRED")) {
|
|
_error = lang(lng_edit_error);
|
|
} else if (err == qstr("MESSAGE_NOT_MODIFIED")) {
|
|
closeBox();
|
|
return true;
|
|
} else if (err == qstr("MESSAGE_EMPTY")) {
|
|
_field->setFocus();
|
|
_field->showError();
|
|
} else {
|
|
_error = lang(lng_edit_error);
|
|
}
|
|
update();
|
|
return true;
|
|
}
|