new photo / file sending, photo always can be sent with caption

This commit is contained in:
John Preston 2015-10-27 22:41:13 -04:00
parent bb416b520a
commit e2f83e1662
12 changed files with 162 additions and 911 deletions

View File

@ -144,8 +144,6 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
"lng_bad_name" = "Please enter your first and last name.";
"lng_bad_photo" = "Bad image selected.";
"lng_bad_image_for_photo" = "This image can't be sent that way.\nWould you like to send it as a file?";
"lng_signin_title" = "Cloud password check";
"lng_signin_desc" = "Please enter your cloud password.";
"lng_signin_recover_desc" = "Please enter the code from the e-mail.";

View File

@ -29,7 +29,6 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxWideWidth)
, _file(file)
, _img(0)
, _thumbx(0)
, _thumby(0)
, _thumbw(0)
@ -37,10 +36,12 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
, _namew(0)
, _textw(0)
, _caption(this, st::confirmCaptionArea, lang(lng_photo_caption))
, _compressed(this, lang(lng_send_image_compressed), cCompressPastedImage())
, _compressedFromSettings(_file->type == PrepareAuto)
, _compressed(this, lang(lng_send_image_compressed), _compressedFromSettings ? cCompressPastedImage() : true)
, _send(this, lang(lng_send_button), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
, _replyTo(_file->to.replyTo) {
, _replyTo(_file->to.replyTo)
, _confirmed(false) {
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
if (_file->photo.type() != mtpc_photoEmpty) {
@ -113,91 +114,7 @@ PhotoSendBox::PhotoSendBox(const FileLoadResultPtr &file) : AbstractBox(st::boxW
prepare();
}
PhotoSendBox::PhotoSendBox(const ReadyLocalMedia &img) : AbstractBox(st::boxWideWidth)
, _img(new ReadyLocalMedia(img))
, _thumbx(0)
, _thumby(0)
, _thumbw(0)
, _thumbh(0)
, _namew(0)
, _textw(0)
, _caption(this, st::confirmCaptionArea, lang(lng_photo_caption))
, _compressed(this, lang(lng_send_image_compressed), cCompressPastedImage())
, _send(this, lang(lng_send_button), st::defaultBoxButton)
, _cancel(this, lang(lng_cancel), st::cancelBoxButton)
, _replyTo(img.replyTo) {
connect(&_send, SIGNAL(clicked()), this, SLOT(onSend()));
connect(&_cancel, SIGNAL(clicked()), this, SLOT(onClose()));
if (_img->type == PreparePhoto) {
int32 maxW = 0, maxH = 0;
for (PreparedPhotoThumbs::const_iterator i = _img->photoThumbs.cbegin(), e = _img->photoThumbs.cend(); i != e; ++i) {
if (i->width() >= maxW && i->height() >= maxH) {
_thumb = *i;
maxW = _thumb.width();
maxH = _thumb.height();
}
}
int32 tw = _thumb.width(), th = _thumb.height();
if (!tw || !th) {
tw = th = 1;
}
_thumbw = width() - 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 = (width() - _thumbw) / 2;
_thumb = QPixmap::fromImage(_thumb.toImage().scaled(_thumbw * cIntRetinaFactor(), _thumbh * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly);
_thumb.setDevicePixelRatio(cRetinaFactor());
} else {
_compressed.hide();
if (!_img->photoThumbs.isEmpty()) {
_thumb = _img->photoThumbs.cbegin().value();
int32 tw = _thumb.width(), th = _thumb.height();
if (_thumb.isNull() || !tw || !th) {
_thumbw = _thumbx = _thumby = 0;
} else if (tw > th) {
_thumbw = (tw * st::mediaThumbSize) / th;
_thumbx = (_thumbw - st::mediaThumbSize) / 2;
_thumby = 0;
} else {
_thumbw = st::mediaThumbSize;
_thumbx = 0;
_thumby = ((th * _thumbw) / tw - st::mediaThumbSize) / 2;
}
}
if (_thumbw) {
_thumb = QPixmap::fromImage(_thumb.toImage().scaledToWidth(_thumbw * cIntRetinaFactor(), Qt::SmoothTransformation), Qt::ColorOnly);
_thumb.setDevicePixelRatio(cRetinaFactor());
}
_name = _img->filename;
_namew = st::mediaFont->width(_name);
_size = formatSizeText(_img->filesize);
_textw = qMax(_namew, st::mediaFont->width(_size));
}
updateBoxSize();
_caption.setMaxLength(MaxPhotoCaption);
_caption.setCtrlEnterSubmit(CtrlEnterSubmitBoth);
connect(&_compressed, SIGNAL(changed()), this, SLOT(onCompressedChange()));
connect(&_caption, SIGNAL(resized()), this, SLOT(onCaptionResized()));
connect(&_caption, SIGNAL(submitted(bool)), this, SLOT(onSend(bool)));
connect(&_caption, SIGNAL(cancelled()), this, SLOT(onClose()));
prepare();
}
PhotoSendBox::PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) : AbstractBox(st::boxWideWidth)
, _img(0)
, _thumbx(0)
, _thumby(0)
, _thumbw(0)
@ -242,7 +159,7 @@ void PhotoSendBox::onCaptionResized() {
}
void PhotoSendBox::updateBoxSize() {
if ((_file && _file->type == PreparePhoto) || (_img && _img->type == PreparePhoto)) {
if (_file && _file->type == PreparePhoto) {
setMaxHeight(st::boxPhotoPadding.top() + _thumbh + st::boxPhotoPadding.bottom() + st::boxPhotoCompressedPadding.top() + _compressed.height() + (_compressed.checked() ? (st::boxPhotoCompressedPadding.bottom() + _caption.height()) : 0) + st::boxButtonPadding.top() + _send.height() + st::boxButtonPadding.bottom());
} else {
setMaxHeight(st::boxPhotoPadding.top() + st::mediaPadding.top() + st::mediaThumbSize + st::mediaPadding.bottom() + st::boxPhotoPadding.bottom() + st::boxButtonPadding.top() + _send.height() + st::boxButtonPadding.bottom());
@ -261,7 +178,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) {
Painter p(this);
if (paint(p)) return;
if ((_file && _file->type == PreparePhoto) || (_img && _img->type == PreparePhoto)) {
if (_file && _file->type == PreparePhoto) {
if (_thumbx > st::boxPhotoPadding.left()) {
p.fillRect(st::boxPhotoPadding.left(), st::boxPhotoPadding.top(), _thumbx - st::boxPhotoPadding.left(), _thumbh, st::confirmBg->b);
}
@ -283,7 +200,7 @@ void PhotoSendBox::paintEvent(QPaintEvent *e) {
if (_thumbw) {
int32 rf(cIntRetinaFactor());
p.drawPixmap(QPoint(x + st::mediaPadding.left(), y + st::mediaPadding.top()), _thumb, QRect(_thumbx * rf, _thumby * rf, st::mediaThumbSize * rf, st::mediaThumbSize * rf));
} else if (_file || _img) {
} else if (_file) {
p.drawPixmap(QPoint(x + st::mediaPadding.left(), y + st::mediaPadding.top()), App::sprite(), st::mediaDocOutImg);
} else {
p.drawPixmap(x + st::mediaPadding.left(), y + st::mediaPadding.top(), userDefPhoto(1)->pix(st::mediaThumbSize));
@ -311,11 +228,11 @@ void PhotoSendBox::resizeEvent(QResizeEvent *e) {
}
void PhotoSendBox::closePressed() {
if (App::main()) {
if (!_confirmed && App::main()) {
if (_file) {
App::main()->onSendFileCancel(_file);
} else {
App::main()->cancelSendImage();
App::main()->onShareContactCancel();
}
}
}
@ -330,7 +247,7 @@ void PhotoSendBox::hideAll() {
void PhotoSendBox::showAll() {
_send.show();
_cancel.show();
if ((_file && _file->type == PreparePhoto) || (_img && _img->type == PreparePhoto)) {
if (_file && _file->type == PreparePhoto) {
_compressed.show();
if (_compressed.checked()) {
_caption.show();
@ -348,52 +265,31 @@ void PhotoSendBox::showDone() {
}
void PhotoSendBox::onSend(bool ctrlShiftEnter) {
if (_file) {
if (_compressed.isHidden()) {
if (_file->type == PrepareAuto) {
_file->type = PrepareDocument;
}
} else {
if (_compressed.checked() != cCompressPastedImage()) {
cSetCompressPastedImage(_compressed.checked());
Local::writeUserSettings();
}
if (_compressed.checked()) {
_file->type = PreparePhoto;
if (App::main()) {
if (_file) {
if (_compressed.isHidden()) {
if (_file->type == PrepareAuto) {
_file->type = PrepareDocument;
}
} else {
_file->type = PrepareDocument;
if (_compressedFromSettings && _compressed.checked() != cCompressPastedImage()) {
cSetCompressPastedImage(_compressed.checked());
Local::writeUserSettings();
}
if (_compressed.checked()) {
_file->type = PreparePhoto;
} else {
_file->type = PrepareDocument;
}
}
}
if (!_caption.isHidden()) {
_file->photoCaption = prepareText(_caption.getLastText(), true);
}
if (App::main()) App::main()->onSendFileConfirm(_file, ctrlShiftEnter);
onClose();
return;
}
if (!_img) {
if (App::main()) App::main()->confirmShareContact(ctrlShiftEnter, _phone, _fname, _lname, _replyTo);
} else {
if (!_compressed.isHidden()) {
if (_compressed.checked() != cCompressPastedImage()) {
cSetCompressPastedImage(_compressed.checked());
Local::writeUserSettings();
if (!_caption.isHidden()) {
_file->photoCaption = prepareText(_caption.getLastText(), true);
}
}
if (_compressed.isHidden() || _compressed.checked()) {
_img->ctrlShiftEnter = ctrlShiftEnter;
_img->caption = _caption.isHidden() ? QString() : prepareText(_caption.getLastText(), true);
if (App::main()) App::main()->confirmSendImage(*_img);
App::main()->onSendFileConfirm(_file, ctrlShiftEnter);
} else {
if (App::main()) App::main()->confirmSendImageUncompressed(ctrlShiftEnter, _replyTo);
App::main()->onShareContactConfirm(_phone, _fname, _lname, _replyTo, ctrlShiftEnter);
}
}
emit confirmed();
emit closed();
}
PhotoSendBox::~PhotoSendBox() {
delete _img;
closePressed();
_confirmed = true;
onClose();
}

View File

@ -29,7 +29,6 @@ class PhotoSendBox : public AbstractBox {
public:
PhotoSendBox(const FileLoadResultPtr &file);
PhotoSendBox(const ReadyLocalMedia &img);
PhotoSendBox(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
void keyPressEvent(QKeyEvent *e);
void paintEvent(QPaintEvent *e);
@ -43,8 +42,6 @@ public:
}
}
~PhotoSendBox();
signals:
void confirmed();
@ -68,11 +65,11 @@ private:
void updateBoxSize();
FileLoadResultPtr _file;
ReadyLocalMedia *_img;
int32 _thumbx, _thumby, _thumbw, _thumbh;
QString _name, _size;
int32 _namew, _textw;
InputArea _caption;
bool _compressedFromSettings;
Checkbox _compressed;
BoxButton _send, _cancel;
QPixmap _thumb;
@ -80,5 +77,6 @@ private:
QString _phone, _fname, _lname;
MsgId _replyTo;
bool _confirmed;
};

View File

@ -747,8 +747,6 @@ PeerData *DialogsInner::updateFromParentDrag(QPoint globalPos) {
lastMousePos = globalPos;
selByMouse = true;
onUpdateSelected(true);
update();
if (_state == DefaultState) {
if (sel) return sel->history->peer;
} else if (_state == FilteredState || _state == SearchedState) {

View File

@ -52,7 +52,7 @@ void FileUploader::uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &me
sendNext();
}
void FileUploader::uploadFile(const FullMsgId &msgId, const FileLoadResultPtr &file) {
void FileUploader::upload(const FullMsgId &msgId, const FileLoadResultPtr &file) {
if (file->type == PreparePhoto) {
App::feedPhoto(file->photo, file->photoThumbs);
} else if (file->type == PrepareDocument) {

View File

@ -29,7 +29,7 @@ public:
FileUploader();
void uploadMedia(const FullMsgId &msgId, const ReadyLocalMedia &image);
void uploadFile(const FullMsgId &msgId, const FileLoadResultPtr &file);
void upload(const FullMsgId &msgId, const FileLoadResultPtr &file);
int32 currentOffset(const FullMsgId &msgId) const; // -1 means file not found
int32 fullSize(const FullMsgId &msgId) const;

View File

@ -1670,7 +1670,7 @@ bool MessageField::canInsertFromMimeData(const QMimeData *source) const {
++files;
}
}
if (files > 1) return false;
if (files > 1) return false; // multiple confirm with "compressed" checkbox
}
if (source->hasImage()) return true;
return FlatTextarea::canInsertFromMimeData(source);
@ -1686,17 +1686,17 @@ void MessageField::insertFromMimeData(const QMimeData *source) {
++files;
}
}
if (files > 1) return;
if (files) {
QString file(url.toLocalFile());
history->uploadFile(file);
if (files == 1) {
history->uploadFile(url.toLocalFile(), PrepareAuto, FileLoadAlwaysConfirm);
return;
}
if (files > 1) return;
//if (files > 1) return uploadFiles(files, PrepareAuto); // multiple confirm with "compressed" checkbox
}
if (source->hasImage()) {
QImage img = qvariant_cast<QImage>(source->imageData());
if (!img.isNull()) {
history->uploadImage(img, FileLoadAlwaysConfirm, source->text());
history->uploadImage(img, PrepareAuto, FileLoadAlwaysConfirm, source->text());
return;
}
}
@ -2403,11 +2403,8 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _attachDragDocument(this)
, _attachDragPhoto(this)
, _fileLoader(this, FileLoaderQueueStopTimeout)
, _imageLoader(this)
, _synthedTextUpdate(false)
, _serviceImageCacheSize(0)
, _confirmImageId(0)
, _confirmWithText(false)
, _confirmWithTextId(0)
, _titlePeerTextWidth(0)
, _a_show(animFunc(this, &HistoryWidget::animStep_show))
@ -2441,8 +2438,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
connect(&_field, SIGNAL(tabbed()), this, SLOT(onFieldTabbed()));
connect(&_field, SIGNAL(resized()), this, SLOT(onFieldResize()));
connect(&_field, SIGNAL(focused()), this, SLOT(onFieldFocused()));
connect(&_imageLoader, SIGNAL(imageReady()), this, SLOT(onPhotoReady()));
connect(&_imageLoader, SIGNAL(imageFailed(quint64)), this, SLOT(onPhotoFailed(quint64)));
connect(&_field, SIGNAL(changed()), this, SLOT(onTextChange()));
connect(&_field, SIGNAL(spacedReturnedPasted()), this, SLOT(onPreviewParse()));
connect(&_field, SIGNAL(linksChanged()), this, SLOT(onPreviewCheck()));
@ -2711,7 +2706,7 @@ void HistoryWidget::onRecordDone(QByteArray result, qint32 samples) {
App::wnd()->activateWindow();
int32 duration = samples / AudioVoiceMsgFrequency;
_imageLoader.append(result, duration, _peer->id, _broadcast.checked(), replyToId(), PrepareAudio);
_fileLoader.addTask(new FileLoadTask(result, duration, FileLoadTo(_peer->id, _broadcast.checked(), replyToId())));
cancelReply(lastForceReplyReplied());
}
@ -3991,7 +3986,11 @@ void HistoryWidget::onSendPaths(const PeerId &peer) {
App::main()->showPeerHistory(peer, ShowAtTheEndMsgId);
if (!_history) return;
uploadMedias(cSendPaths(), PrepareDocument);
if (cSendPaths().size() == 1) {
uploadFile(cSendPaths().at(0), PrepareAuto);
} else {
uploadFiles(cSendPaths(), PrepareDocument);
}
}
History *HistoryWidget::history() const {
@ -4166,14 +4165,12 @@ void HistoryWidget::onPhotoSelect() {
QString filter(qsl("Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;Photo files (*") + photoExtensions.join(qsl(" *")) + qsl(");;All files (*.*)"));
QStringList files;
QByteArray file;
if (filedialogGetOpenFiles(files, file, lang(lng_choose_images), filter)) {
if (!file.isEmpty()) {
uploadMedia(file, PreparePhoto);
//} else if (files.size() == 1) {
// uploadWithConfirm(files.at(0), false, true);
} else if (!files.isEmpty()) {
uploadMedias(files, PreparePhoto);
QByteArray content;
if (filedialogGetOpenFiles(files, content, lang(lng_choose_images), filter)) {
if (!content.isEmpty()) {
uploadFileContent(content, PreparePhoto);
} else {
uploadFiles(files, PreparePhoto);
}
}
}
@ -4196,14 +4193,12 @@ void HistoryWidget::onDocumentSelect() {
QString filter(qsl("All files (*.*);;Image files (*") + imgExtensions.join(qsl(" *")) + qsl(");;Photo files (*") + photoExtensions.join(qsl(" *")) + qsl(")"));
QStringList files;
QByteArray file;
if (filedialogGetOpenFiles(files, file, lang(lng_choose_images), filter)) {
if (!file.isEmpty()) {
uploadMedia(file, PrepareDocument);
//} else if (files.size() == 1) {
// uploadWithConfirm(files.at(0), false, false);
} else if (!files.isEmpty()) {
uploadMedias(files, PrepareDocument);
QByteArray content;
if (filedialogGetOpenFiles(files, content, lang(lng_choose_images), filter)) {
if (!content.isEmpty()) {
uploadFileContent(content, PrepareDocument);
} else {
uploadFiles(files, PrepareDocument);
}
}
}
@ -4504,16 +4499,12 @@ void HistoryWidget::onPhotoDrop(const QMimeData *data) {
QImage image = qvariant_cast<QImage>(data->imageData());
if (image.isNull()) return;
uploadImage(image, FileLoadNoForceConfirm, data->text());
uploadImage(image, PreparePhoto, FileLoadNoForceConfirm, data->text());
}
return;
}
//if (files.size() == 1) {
// uploadWithConfirm(files.at(0), false, true);
//} else {
uploadMedias(files, PreparePhoto);
//}
uploadFiles(files, PreparePhoto);
}
void HistoryWidget::onDocumentDrop(const QMimeData *data) {
@ -4522,11 +4513,7 @@ void HistoryWidget::onDocumentDrop(const QMimeData *data) {
QStringList files = getMediasFromMime(data);
if (files.isEmpty()) return;
//if (files.size() == 1) {
// uploadWithConfirm(files.at(0), false, false);
//} else {
uploadMedias(files, PrepareDocument);
//}
uploadFiles(files, PrepareDocument);
}
void HistoryWidget::onFilesDrop(const QMimeData *data) {
@ -4536,16 +4523,15 @@ void HistoryWidget::onFilesDrop(const QMimeData *data) {
QImage image = qvariant_cast<QImage>(data->imageData());
if (image.isNull()) return;
uploadImage(image, FileLoadNoForceConfirm, data->text());
uploadImage(image, PrepareAuto, FileLoadNoForceConfirm, data->text());
}
return;
}
//if (files.size() == 1) {
// uploadWithConfirm(files.at(0), false, true);
//} else {
uploadMedias(files, PrepareAuto);
//}
if (files.size() == 1) {
uploadFile(files.at(0), PrepareAuto);
}
// uploadFiles(files, PrepareAuto); // multiple confirm with "compressed" checkbox
}
void HistoryWidget::onKbToggle(bool manual) {
@ -4806,176 +4792,63 @@ void HistoryWidget::onFieldCursorChanged() {
onDraftSaveDelayed();
}
void HistoryWidget::uploadImage(const QImage &img, FileLoadForceConfirmType confirm, const QString &source, bool withText) {
void HistoryWidget::uploadImage(const QImage &img, PrepareMediaType type, FileLoadForceConfirmType confirm, const QString &source, bool withText) {
if (!_history) return;
App::wnd()->activateWindow();
FileLoadTask *task = new FileLoadTask(img, FileLoadTo(_peer->id, _broadcast.checked(), replyToId()), confirm, source);
FileLoadTask *task = new FileLoadTask(img, type, FileLoadTo(_peer->id, _broadcast.checked(), replyToId()), confirm, source);
if (withText) {
_confirmWithTextId = task->fileid();
}
_fileLoader.addTask(task);
}
void HistoryWidget::uploadFile(const QString &file, FileLoadForceConfirmType confirm, bool withText) {
void HistoryWidget::uploadFile(const QString &file, PrepareMediaType type, FileLoadForceConfirmType confirm, bool withText) {
if (!_history) return;
App::wnd()->activateWindow();
FileLoadTask *task = new FileLoadTask(file, PrepareAuto, FileLoadTo(_peer->id, _broadcast.checked(), replyToId()), confirm);
FileLoadTask *task = new FileLoadTask(file, type, FileLoadTo(_peer->id, _broadcast.checked(), replyToId()), confirm);
if (withText) {
_confirmWithTextId = task->fileid();
}
_fileLoader.addTask(task);
}
void HistoryWidget::shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText) {
if (!_history || _confirmImageId) return;
void HistoryWidget::uploadFiles(const QStringList &files, PrepareMediaType type) {
if (!_history || files.isEmpty()) return;
if (files.size() == 1) return uploadFile(files.at(0), type);
App::wnd()->activateWindow();
_confirmWithText = withText;
_confirmImageId = 0xFFFFFFFFFFFFFFFFL;
FileLoadTo to(_peer->id, _broadcast.checked(), replyToId());
TasksList tasks;
tasks.reserve(files.size());
for (int32 i = 0, l = files.size(); i < l; ++i) {
tasks.push_back(TaskPtr(new FileLoadTask(files.at(i), type, to, FileLoadNeverConfirm)));
}
_fileLoader.addTasks(tasks);
cancelReply(lastForceReplyReplied());
}
void HistoryWidget::uploadFileContent(const QByteArray &fileContent, PrepareMediaType type) {
if (!_history) return;
App::wnd()->activateWindow();
_fileLoader.addTask(new FileLoadTask(fileContent, type, FileLoadTo(_peer->id, _broadcast.checked(), replyToId())));
cancelReply(lastForceReplyReplied());
}
void HistoryWidget::shareContactWithConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText) {
if (!_history) return;
App::wnd()->activateWindow();
_confirmWithTextId = 0xFFFFFFFFFFFFFFFFL;
App::wnd()->showLayer(new PhotoSendBox(phone, fname, lname, replyTo));
}
void HistoryWidget::uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId replyTo) {
if (!_history || !_confirmImageId || _confirmImage.isNull()) return;
App::wnd()->activateWindow();
PeerId peerId = _peer->id;
if (_confirmWithText) {
onSend(ctrlShiftEnter, replyTo);
}
bool lastKeyboardUsed = lastForceReplyReplied(FullMsgId(_channel, replyTo));
_imageLoader.append(_confirmImage, peerId, _broadcast.checked(), replyTo, PrepareDocument, ctrlShiftEnter);
_confirmImageId = 0;
_confirmWithText = false;
_confirmImage = QImage();
cancelReply(lastKeyboardUsed);
}
void HistoryWidget::uploadMedias(const QStringList &files, PrepareMediaType type) {
if (!_history) return;
App::wnd()->activateWindow();
_imageLoader.append(files, _peer->id, _broadcast.checked(), replyToId(), type);
cancelReply(lastForceReplyReplied());
}
void HistoryWidget::uploadMedia(const QByteArray &fileContent, PrepareMediaType type, PeerId peer) {
if (!peer && !_history) return;
App::wnd()->activateWindow();
_imageLoader.append(fileContent, peer ? peer : _peer->id, _broadcast.checked(), replyToId(), type);
cancelReply(lastForceReplyReplied());
}
void HistoryWidget::onPhotoReady() {
QMutexLocker lock(_imageLoader.readyMutex());
ReadyLocalMedias &list(_imageLoader.readyList());
for (ReadyLocalMedias::const_iterator i = list.cbegin(), e = list.cend(); i != e; ++i) {
if (i->id == _confirmImageId) {
PhotoSendBox *box = new PhotoSendBox(*i);
connect(box, SIGNAL(confirmed()), this, SLOT(onSendConfirmed()));
connect(box, SIGNAL(destroyed(QObject*)), this, SLOT(onSendCancelled()));
App::wnd()->showLayer(box);
} else {
confirmSendImage(*i);
}
}
list.clear();
}
void HistoryWidget::onSendConfirmed() {
if (!_confirmSource.isEmpty()) _confirmSource = QString();
}
void HistoryWidget::onSendCancelled() {
if (!_confirmSource.isEmpty()) {
_field.textCursor().insertText(_confirmSource);
_confirmSource = QString();
}
}
void HistoryWidget::onPhotoFailed(quint64 id) {
}
void HistoryWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) {
if (!_peer) return;
PeerId peerId = _peer->id;
if (0xFFFFFFFFFFFFFFFFL == _confirmImageId) {
if (_confirmWithText) {
onSend(ctrlShiftEnter, replyTo);
}
_confirmImageId = 0;
_confirmWithText = false;
_confirmImage = QImage();
}
shareContact(peerId, phone, fname, lname, replyTo);
}
void HistoryWidget::confirmSendImage(const ReadyLocalMedia &img) {
if (img.id == _confirmImageId) {
if (_confirmWithText) {
onSend(img.ctrlShiftEnter, img.replyTo);
}
_confirmImageId = 0;
_confirmWithText = false;
_confirmImage = QImage();
}
FullMsgId newId(peerToChannel(img.peer), clientMsgId());
connect(App::uploader(), SIGNAL(photoReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onPhotoUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onDocumentUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(thumbDocumentReady(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), this, SLOT(onThumbDocumentUploaded(const FullMsgId&, const MTPInputFile&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioReady(const FullMsgId&, const MTPInputFile&)), this, SLOT(onAudioUploaded(const FullMsgId&, const MTPInputFile&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoProgress(const FullMsgId&)), this, SLOT(onPhotoProgress(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentProgress(const FullMsgId&)), this, SLOT(onDocumentProgress(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioProgress(const FullMsgId&)), this, SLOT(onAudioProgress(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(photoFailed(const FullMsgId&)), this, SLOT(onPhotoFailed(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(documentFailed(const FullMsgId&)), this, SLOT(onDocumentFailed(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioFailed(const FullMsgId&)), this, SLOT(onAudioFailed(const FullMsgId&)), Qt::UniqueConnection);
App::uploader()->uploadMedia(newId, img);
History *h = App::history(img.peer);
fastShowAtEnd(h);
int32 flags = newMessageFlags(h->peer) | MTPDmessage::flag_media; // unread, out
if (img.replyTo) flags |= MTPDmessage::flag_reply_to_msg_id;
bool fromChannelName = h->peer->isChannel() && h->peer->asChannel()->canPublish() && (h->peer->asChannel()->isBroadcast() || img.broadcast);
if (fromChannelName) {
flags |= MTPDmessage::flag_views;
} else {
flags |= MTPDmessage::flag_from_id;
}
if (img.type == PreparePhoto) {
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPPeer(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaPhoto(img.photo, MTP_string(img.caption)), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
} else if (img.type == PrepareDocument) {
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPPeer(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaDocument(img.document), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
} else if (img.type == PrepareAudio) {
if (!h->peer->isChannel()) {
flags |= MTPDmessage_flag_media_unread;
}
h->addNewMessage(MTP_message(MTP_int(flags), MTP_int(newId.msg), MTP_int(fromChannelName ? 0 : MTP::authedId()), peerToMTP(img.peer), MTPPeer(), MTPint(), MTP_int(img.replyTo), MTP_int(unixtime()), MTP_string(""), MTP_messageMediaAudio(img.audio), MTPnullMarkup, MTPnullEntities, MTP_int(1)), NewMessageUnread);
}
if (_peer && img.peer == _peer->id) {
App::main()->historyToDown(_history);
}
App::main()->dialogsToUp();
peerMessagesUpdated(img.peer);
}
void HistoryWidget::cancelSendImage() {
if (_confirmImageId && _confirmWithText) setFieldText(QString());
_confirmImageId = 0;
_confirmWithText = false;
_confirmImage = QImage();
}
void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShiftEnter) {
if (_confirmWithTextId && _confirmWithTextId == file->id) {
onSend(ctrlShiftEnter, file->to.replyTo);
@ -4995,7 +4868,7 @@ void HistoryWidget::confirmSendFile(const FileLoadResultPtr &file, bool ctrlShif
connect(App::uploader(), SIGNAL(documentFailed(const FullMsgId&)), this, SLOT(onDocumentFailed(const FullMsgId&)), Qt::UniqueConnection);
connect(App::uploader(), SIGNAL(audioFailed(const FullMsgId&)), this, SLOT(onAudioFailed(const FullMsgId&)), Qt::UniqueConnection);
App::uploader()->uploadFile(newId, file);
App::uploader()->upload(newId, file);
History *h = App::history(file->to.peer);
@ -5037,6 +4910,23 @@ void HistoryWidget::cancelSendFile(const FileLoadResultPtr &file) {
}
}
void HistoryWidget::confirmShareContact(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter) {
if (!_peer) return;
if (_confirmWithTextId == 0xFFFFFFFFFFFFFFFFL) {
onSend(ctrlShiftEnter, replyTo);
_confirmWithTextId = 0;
}
shareContact(_peer->id, phone, fname, lname, replyTo);
}
void HistoryWidget::cancelShareContact() {
if (_confirmWithTextId == 0xFFFFFFFFFFFFFFFFL) {
setFieldText(QString());
_confirmWithTextId = 0;
}
}
void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, const MTPInputFile &file) {
if (!MTP::authedId()) return;
HistoryItem *item = App::histItemById(newId);
@ -5055,7 +4945,7 @@ void HistoryWidget::onPhotoUploaded(const FullMsgId &newId, const MTPInputFile &
sendFlags |= MTPmessages_SendMessage_flag_broadcast;
}
QString caption = item->getMedia() ? item->getMedia()->getCaption() : QString();
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendPhotoFail, randomId), 0, 0, hist->sendRequestId);
hist->sendRequestId = MTP::send(MTPmessages_SendMedia(MTP_int(sendFlags), item->history()->peer->input, MTP_int(replyTo), MTP_inputMediaUploadedPhoto(file, MTP_string(caption)), MTP_long(randomId), MTPnullMarkup), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, 0, hist->sendRequestId);
}
}

View File

@ -430,18 +430,17 @@ public:
void sendActionDone(const MTPBool &result, mtpRequestId req);
void destroyData();
void uploadImage(const QImage &img, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &source = QString(), bool withText = false);
void uploadFile(const QString &file, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, bool withText = false); // with confirmation
void shareContactConfirmation(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText = false);
void uploadConfirmImageUncompressed(bool ctrlShiftEnter, MsgId replyTo);
void uploadMedias(const QStringList &files, PrepareMediaType type);
void uploadMedia(const QByteArray &fileContent, PrepareMediaType type, PeerId peer = 0);
void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
void confirmSendImage(const ReadyLocalMedia &img);
void cancelSendImage();
void uploadImage(const QImage &img, PrepareMediaType type, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &source = QString(), bool withText = false);
void uploadFile(const QString &file, PrepareMediaType type, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, bool withText = false); // with confirmation
void uploadFiles(const QStringList &files, PrepareMediaType type);
void uploadFileContent(const QByteArray &fileContent, PrepareMediaType type);
void shareContactWithConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool withText = false);
void confirmSendFile(const FileLoadResultPtr &file, bool ctrlShiftEnter);
void cancelSendFile(const FileLoadResultPtr &file);
void confirmShareContact(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter);
void cancelShareContact();
void updateControlsVisibility();
void updateOnlineDisplay(int32 x, int32 w);
@ -608,11 +607,6 @@ public slots:
void onKbToggle(bool manual = true);
void onCmdStart();
void onPhotoReady();
void onSendConfirmed();
void onSendCancelled();
void onPhotoFailed(quint64 id);
void activate();
void onMentionHashtagOrBotCommandInsert(QString str);
void onTextChange();
@ -771,13 +765,9 @@ private:
int32 _selCount; // < 0 - text selected, focus list, not _field
TaskQueue _fileLoader;
LocalImageLoader _imageLoader;
bool _synthedTextUpdate;
int64 _serviceImageCacheSize;
QImage _confirmImage;
PhotoId _confirmImageId;
bool _confirmWithText;
QString _confirmSource;
uint64 _confirmWithTextId;

View File

@ -29,398 +29,6 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
#include "lang.h"
#include "boxes/confirmbox.h"
LocalImageLoaderPrivate::LocalImageLoaderPrivate(LocalImageLoader *loader, QThread *thread) : QObject(0)
, loader(loader)
{
moveToThread(thread);
connect(loader, SIGNAL(needToPrepare()), this, SLOT(prepareImages()));
connect(this, SIGNAL(imageReady()), loader, SLOT(onImageReady()));
connect(this, SIGNAL(imageFailed(quint64)), loader, SLOT(onImageFailed(quint64)));
};
void LocalImageLoaderPrivate::prepareImages() {
QString file, filename, mime, stickerMime = qsl("image/webp");
int32 filesize = 0;
QImage img;
QByteArray data;
PeerId peer;
uint64 id, thumbId = 0;
int32 duration = 0;
QString thumbExt = "jpg";
PrepareMediaType type;
bool animated = false;
bool broadcast = false;
bool ctrlShiftEnter = false;
MsgId replyTo;
{
QMutexLocker lock(loader->toPrepareMutex());
ToPrepareMedias &list(loader->toPrepareMedias());
if (list.isEmpty()) return;
file = list.front().file;
img = list.front().img;
data = list.front().data;
peer = list.front().peer;
id = list.front().id;
type = list.front().type;
duration = list.front().duration;
broadcast = list.front().broadcast;
ctrlShiftEnter = list.front().ctrlShiftEnter;
replyTo = list.front().replyTo;
}
if (img.isNull()) {
if (!file.isEmpty()) {
QFileInfo info(file);
if (type == PrepareAuto) {
QString lower(file.toLower());
const QStringList &photoExtensions(cPhotoExtensions());
for (QStringList::const_iterator i = photoExtensions.cbegin(), e = photoExtensions.cend(); i != e; ++i) {
if (lower.lastIndexOf(*i) == lower.size() - i->size()) {
if (info.size() < MaxUploadPhotoSize) {
type = PreparePhoto;
break;
}
}
}
if (type == PrepareAuto && info.size() < MaxUploadDocumentSize) {
type = PrepareDocument;
}
}
if (type != PrepareAuto && info.size() < MaxUploadPhotoSize) {
bool opaque = (mime != stickerMime);
img = App::readImage(file, 0, opaque, &animated);
if (animated) {
type = PrepareDocument;
}
}
if (type == PrepareDocument) {
mime = mimeTypeForFile(info).name();
}
filename = info.fileName();
filesize = info.size();
} else if (!data.isEmpty()) {
if (type != PrepareAudio) {
img = App::readImage(data, 0, true, &animated);
if (type == PrepareAuto) {
if (!img.isNull() && data.size() < MaxUploadPhotoSize) {
type = PreparePhoto;
} else if (data.size() < MaxUploadDocumentSize) {
type = PrepareDocument;
} else {
img = QImage();
}
}
}
MimeType mimeType = mimeTypeForData(data);
if (type == PrepareDocument || type == PrepareAudio) {
mime = mimeType.name();
}
if (mime == "image/jpeg") {
filename = filedialogDefaultName(qsl("image"), qsl(".jpg"), QString(), true);
} else if (type == PrepareAudio) {
filename = filedialogDefaultName(qsl("audio"), qsl(".ogg"), QString(), true);
mime = "audio/ogg";
} else {
QString ext;
QStringList patterns = mimeType.globPatterns();
if (!patterns.isEmpty()) {
ext = patterns.front().replace('*', QString());
}
filename = filedialogDefaultName((type == PrepareAudio) ? qsl("audio") : qsl("doc"), ext, QString(), true);
}
filesize = data.size();
}
} else {
if (type == PrepareDocument) {
filename = filedialogDefaultName(qsl("image"), qsl(".png"), QString(), true);
mime = mimeTypeForName("image/png").name();
data = QByteArray();
{
QBuffer b(&data);
img.save(&b, "PNG");
}
filesize = data.size();
} else {
if (img.hasAlphaChannel()) {
QImage solid(img.width(), img.height(), QImage::Format_ARGB32_Premultiplied);
solid.fill(st::white->c);
{
QPainter(&solid).drawImage(0, 0, img);
}
img = solid;
}
type = PreparePhoto;
filename = qsl("Untitled.jpg");
filesize = 0;
}
}
if ((img.isNull() && ((type != PrepareDocument && type != PrepareAudio) || !filesize)) || type == PrepareAuto || (img.isNull() && file.isEmpty() && data.isEmpty())) { // if could not decide what type
{
QMutexLocker lock(loader->toPrepareMutex());
ToPrepareMedias &list(loader->toPrepareMedias());
list.pop_front();
}
QTimer::singleShot(1, this, SLOT(prepareImages()));
emit imageFailed(id);
} else {
PreparedPhotoThumbs photoThumbs;
QVector<MTPPhotoSize> photoSizes;
QVector<MTPDocumentAttribute> attributes(1, MTP_documentAttributeFilename(MTP_string(filename)));
MTPPhotoSize thumb(MTP_photoSizeEmpty(MTP_string("")));
MTPPhoto photo(MTP_photoEmpty(MTP_long(0)));
MTPDocument document(MTP_documentEmpty(MTP_long(0)));
MTPAudio audio(MTP_audioEmpty(MTP_long(0)));
bool isSong = false;
QByteArray jpeg;
if (type == PrepareDocument) {
if (mime == qstr("audio/mp3") || mime == qstr("audio/m4a") || mime == qstr("audio/aac") || mime == qstr("audio/ogg") || mime == qstr("audio/flac") ||
filename.endsWith(qstr(".mp3"), Qt::CaseInsensitive) || filename.endsWith(qstr(".m4a"), Qt::CaseInsensitive) ||
filename.endsWith(qstr(".aac"), Qt::CaseInsensitive) || filename.endsWith(qstr(".ogg"), Qt::CaseInsensitive) ||
filename.endsWith(qstr(".flac"), Qt::CaseInsensitive)) {
QImage cover;
QByteArray coverBytes, coverFormat;
MTPDocumentAttribute audioAttribute = audioReadSongAttributes(file, data, cover, coverBytes, coverFormat);
if (audioAttribute.type() == mtpc_documentAttributeAudio) {
attributes.push_back(audioAttribute);
isSong = true;
if (!cover.isNull()) { // cover to thumb
int32 cw = cover.width(), ch = cover.height();
if (cw < 20 * ch && ch < 20 * cw) {
QPixmap full = (cw > 90 || ch > 90) ? QPixmap::fromImage(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(cover, Qt::ColorOnly);
{
QByteArray thumbFormat = "JPG";
int32 thumbQuality = 87;
QBuffer jpegBuffer(&jpeg);
full.save(&jpegBuffer, thumbFormat, thumbQuality);
}
photoThumbs.insert('0', full);
thumb = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0));
thumbId = MTP::nonce<uint64>();
}
}
}
}
}
if (type == PreparePhoto) {
int32 w = img.width(), h = img.height();
QPixmap thumb = (w > 100 || h > 100) ? QPixmap::fromImage(img.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(img);
photoThumbs.insert('s', thumb);
photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
QPixmap medium = (w > 320 || h > 320) ? QPixmap::fromImage(img.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(img);
photoThumbs.insert('m', medium);
photoSizes.push_back(MTP_photoSize(MTP_string("m"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(medium.width()), MTP_int(medium.height()), MTP_int(0)));
QPixmap full = (w > 1280 || h > 1280) ? QPixmap::fromImage(img.scaled(1280, 1280, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(img);
photoThumbs.insert('y', full);
photoSizes.push_back(MTP_photoSize(MTP_string("y"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0)));
{
QBuffer jpegBuffer(&jpeg);
full.save(&jpegBuffer, "JPG", 77);
}
if (!filesize) filesize = jpeg.size();
photo = MTP_photo(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_vector<MTPPhotoSize>(photoSizes));
thumbId = id;
} else if ((type == PrepareVideo || type == PrepareDocument) && !img.isNull() && !isSong) {
int32 w = img.width(), h = img.height();
QByteArray thumbFormat = "JPG";
int32 thumbQuality = 87;
if (animated) {
attributes.push_back(MTP_documentAttributeAnimated());
} else if (mime == stickerMime && w > 0 && h > 0 && w <= StickerMaxSize && h <= StickerMaxSize && filesize < StickerInMemory) {
attributes.push_back(MTP_documentAttributeSticker(MTP_string(""), MTP_inputStickerSetEmpty()));
thumbFormat = "webp";
thumbExt = qsl("webp");
}
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
if (w < 20 * h && h < 20 * w) {
QPixmap full = (w > 90 || h > 90) ? QPixmap::fromImage(img.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(img, Qt::ColorOnly);
{
QBuffer jpegBuffer(&jpeg);
full.save(&jpegBuffer, thumbFormat, thumbQuality);
}
photoThumbs.insert('0', full);
thumb = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0));
thumbId = MTP::nonce<uint64>();
}
}
if (type == PrepareDocument) {
document = MTP_document(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_string(mime), MTP_int(filesize), thumb, MTP_int(MTP::maindc()), MTP_vector<MTPDocumentAttribute>(attributes));
} else if (type == PrepareAudio) {
audio = MTP_audio(MTP_long(id), MTP_long(0), MTP_int(unixtime()), MTP_int(duration), MTP_string(mime), MTP_int(filesize), MTP_int(MTP::maindc()));
}
{
QMutexLocker lock(loader->readyMutex());
loader->readyList().push_back(ReadyLocalMedia(type, file, filename, filesize, data, id, thumbId, thumbExt, peer, photo, audio, photoThumbs, document, jpeg, broadcast, ctrlShiftEnter, replyTo));
}
{
QMutexLocker lock(loader->toPrepareMutex());
ToPrepareMedias &list(loader->toPrepareMedias());
list.pop_front();
}
QTimer::singleShot(1, this, SLOT(prepareImages()));
emit imageReady();
}
}
LocalImageLoaderPrivate::~LocalImageLoaderPrivate() {
loader = 0;
}
LocalImageLoader::LocalImageLoader(QObject *parent) : QObject(parent), thread(0), priv(0) {
}
void LocalImageLoader::append(const QStringList &files, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t) {
{
QMutexLocker lock(toPrepareMutex());
for (QStringList::const_iterator i = files.cbegin(), e = files.cend(); i != e; ++i) {
toPrepare.push_back(ToPrepareMedia(*i, peer, t, broadcast, false, replyTo));
}
}
if (!thread) {
thread = new QThread();
priv = new LocalImageLoaderPrivate(this, thread);
thread->start();
}
emit needToPrepare();
}
PhotoId LocalImageLoader::append(const QByteArray &img, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t) {
PhotoId result = 0;
{
QMutexLocker lock(toPrepareMutex());
toPrepare.push_back(ToPrepareMedia(img, peer, t, broadcast, false, replyTo));
result = toPrepare.back().id;
}
if (!thread) {
thread = new QThread();
priv = new LocalImageLoaderPrivate(this, thread);
thread->start();
}
emit needToPrepare();
return result;
}
AudioId LocalImageLoader::append(const QByteArray &audio, int32 duration, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t) {
AudioId result = 0;
{
QMutexLocker lock(toPrepareMutex());
toPrepare.push_back(ToPrepareMedia(audio, duration, peer, t, broadcast, false, replyTo));
result = toPrepare.back().id;
}
if (!thread) {
thread = new QThread();
priv = new LocalImageLoaderPrivate(this, thread);
thread->start();
}
emit needToPrepare();
return result;
}
PhotoId LocalImageLoader::append(const QImage &img, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t, bool ctrlShiftEnter) {
PhotoId result = 0;
{
QMutexLocker lock(toPrepareMutex());
toPrepare.push_back(ToPrepareMedia(img, peer, t, broadcast, ctrlShiftEnter, replyTo));
result = toPrepare.back().id;
}
if (!thread) {
thread = new QThread();
priv = new LocalImageLoaderPrivate(this, thread);
thread->start();
}
emit needToPrepare();
return result;
}
PhotoId LocalImageLoader::append(const QString &file, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t) {
PhotoId result = 0;
{
QMutexLocker lock(toPrepareMutex());
toPrepare.push_back(ToPrepareMedia(file, peer, t, broadcast, false, replyTo));
result = toPrepare.back().id;
}
if (!thread) {
thread = new QThread();
priv = new LocalImageLoaderPrivate(this, thread);
thread->start();
}
emit needToPrepare();
return result;
}
void LocalImageLoader::onImageReady() {
{
QMutexLocker lock(toPrepareMutex());
if (toPrepare.isEmpty()) {
if (priv) priv->deleteLater();
priv = 0;
if (thread) thread->deleteLater();
thread = 0;
}
}
emit imageReady();
}
void LocalImageLoader::onImageFailed(quint64 id) {
{
QMutexLocker lock(toPrepareMutex());
if (toPrepare.isEmpty()) {
if (priv) priv->deleteLater();
priv = 0;
if (thread) thread->deleteLater();
thread = 0;
}
}
emit imageFailed(id);
}
QMutex *LocalImageLoader::readyMutex() {
return &readyLock;
}
ReadyLocalMedias &LocalImageLoader::readyList() {
return ready;
}
QMutex *LocalImageLoader::toPrepareMutex() {
return &toPrepareLock;
}
ToPrepareMedias &LocalImageLoader::toPrepareMedias() {
return toPrepare;
}
LocalImageLoader::~LocalImageLoader() {
delete priv;
delete thread;
}
TaskQueue::TaskQueue(QObject *parent, int32 stopTimeoutMs) : QObject(parent), _thread(0), _worker(0), _stopTimer(0) {
if (stopTimeoutMs > 0) {
_stopTimer = new QTimer(this);
@ -435,6 +43,22 @@ TaskId TaskQueue::addTask(TaskPtr task) {
QMutexLocker lock(&_tasksToProcessMutex);
_tasksToProcess.push_back(task);
}
wakeThread();
return task->id();
}
void TaskQueue::addTasks(const TasksList &tasks) {
{
QMutexLocker lock(&_tasksToProcessMutex);
_tasksToProcess.append(tasks);
}
wakeThread();
}
void TaskQueue::wakeThread() {
if (!_thread) {
_thread = new QThread();
@ -448,8 +72,6 @@ TaskId TaskQueue::addTask(TaskPtr task) {
}
if (_stopTimer) _stopTimer->stop();
emit taskAdded();
return task->id();
}
void TaskQueue::cancelTask(TaskId id) {
@ -557,11 +179,11 @@ FileLoadTask::FileLoadTask(const QByteArray &content, PrepareMediaType type, con
, _result(0) {
}
FileLoadTask::FileLoadTask(const QImage &image, const FileLoadTo &to, FileLoadForceConfirmType confirm, const QString &originalText) : _id(MTP::nonce<uint64>())
FileLoadTask::FileLoadTask(const QImage &image, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm, const QString &originalText) : _id(MTP::nonce<uint64>())
, _to(to)
, _image(image)
, _duration(0)
, _type(PrepareAuto)
, _type(type)
, _confirm(confirm)
, _originalText(originalText)
, _result(0) {
@ -701,7 +323,7 @@ void FileLoadTask::process() {
if (w < 20 * h && h < 20 * w) {
if (animated) {
attributes.push_back(MTP_documentAttributeAnimated());
} else {
} else if (_type != PrepareDocument) {
QPixmap thumb = (w > 100 || h > 100) ? QPixmap::fromImage(fullimage.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(fullimage);
photoThumbs.insert('s', thumb);
photoSizes.push_back(MTP_photoSize(MTP_string("s"), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(thumb.width()), MTP_int(thumb.height()), MTP_int(0)));
@ -787,6 +409,9 @@ void FileLoadTask::finish() {
if (confirm) {
App::wnd()->showLayerLast(new PhotoSendBox(_result));
} else {
if (_result->type == PrepareAuto) {
_result->type = (_result->photo.type() != mtpc_photoEmpty) ? PreparePhoto : PrepareDocument;
}
App::main()->onSendFileConfirm(_result, false);
}
}

View File

@ -86,72 +86,6 @@ struct ReadyLocalMedia {
ReadyLocalMedia() : type(PrepareAuto) { // temp
}
};
typedef QList<ReadyLocalMedia> ReadyLocalMedias;
class LocalImageLoader;
class LocalImageLoaderPrivate : public QObject {
Q_OBJECT
public:
LocalImageLoaderPrivate(LocalImageLoader *loader, QThread *thread);
~LocalImageLoaderPrivate();
public slots:
void prepareImages();
signals:
void imageReady();
void imageFailed(quint64 id);
private:
LocalImageLoader *loader;
};
class LocalImageLoader : public QObject {
Q_OBJECT
public:
LocalImageLoader(QObject *parent);
void append(const QStringList &files, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t);
PhotoId append(const QByteArray &img, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t);
AudioId append(const QByteArray &audio, int32 duration, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t);
PhotoId append(const QImage &img, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t, bool ctrlShiftEnter = false);
PhotoId append(const QString &file, const PeerId &peer, bool broadcast, MsgId replyTo, PrepareMediaType t);
QMutex *readyMutex();
ReadyLocalMedias &readyList();
QMutex *toPrepareMutex();
ToPrepareMedias &toPrepareMedias();
~LocalImageLoader();
public slots:
void onImageReady();
void onImageFailed(quint64 id);
signals:
void imageReady();
void imageFailed(quint64 id);
void needToPrepare();
private:
ReadyLocalMedias ready;
ToPrepareMedias toPrepare;
QMutex readyLock, toPrepareLock;
QThread *thread;
LocalImageLoaderPrivate *priv;
};
class Task {
public:
@ -167,6 +101,7 @@ public:
};
typedef QSharedPointer<Task> TaskPtr;
typedef QList<TaskPtr> TasksList;
class TaskQueueWorker;
class TaskQueue : public QObject {
@ -177,6 +112,7 @@ public:
TaskQueue(QObject *parent, int32 stopTimeoutMs = 0); // <= 0 - never stop worker
TaskId addTask(TaskPtr task);
void addTasks(const TasksList &tasks);
void cancelTask(TaskId id); // this task finish() won't be called
TaskId addTask(Task *task) {
@ -196,10 +132,11 @@ public slots:
private:
typedef QList<TaskPtr> Tasks;
friend class TaskQueueWorker;
Tasks _tasksToProcess, _tasksToFinish;
void wakeThread();
TasksList _tasksToProcess, _tasksToFinish;
QMutex _tasksToProcessMutex, _tasksToFinishMutex;
QThread *_thread;
TaskQueueWorker *_worker;
@ -301,7 +238,7 @@ public:
FileLoadTask(const QString &filepath, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm);
FileLoadTask(const QByteArray &content, PrepareMediaType type, const FileLoadTo &to);
FileLoadTask(const QImage &image, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &originalText = QString());
FileLoadTask(const QImage &image, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm = FileLoadNoForceConfirm, const QString &originalText = QString());
FileLoadTask(const QByteArray &audio, int32 duration, const FileLoadTo &to);
uint64 fileid() const {

View File

@ -1069,23 +1069,6 @@ void MainWidget::checkedHistory(PeerData *peer, const MTPmessages_Messages &resu
}
}
bool MainWidget::sendPhotoFail(uint64 randomId, const RPCError &error) {
if (mtpIsFlood(error)) return false;
if (error.type() == qsl("PHOTO_INVALID_DIMENSIONS")) {
if (_resendImgRandomIds.isEmpty()) {
ConfirmBox *box = new ConfirmBox(lang(lng_bad_image_for_photo));
connect(box, SIGNAL(confirmed()), this, SLOT(onResendAsDocument()));
connect(box, SIGNAL(cancelled()), this, SLOT(onCancelResend()));
connect(box, SIGNAL(destroyed(QObject*)), this, SLOT(onCancelResend()));
App::wnd()->showLayer(box);
}
_resendImgRandomIds.push_back(randomId);
return true;
}
return sendMessageFail(error);
}
bool MainWidget::sendMessageFail(const RPCError &error) {
if (mtpIsFlood(error)) return false;
@ -1096,51 +1079,6 @@ bool MainWidget::sendMessageFail(const RPCError &error) {
return false;
}
void MainWidget::onResendAsDocument() {
QMap<History*, bool> historiesToCheck;
QList<uint64> tmp = _resendImgRandomIds;
_resendImgRandomIds.clear();
for (int32 i = 0, l = tmp.size(); i < l; ++i) {
if (HistoryItem *item = App::histItemById(App::histItemByRandom(tmp.at(i)))) {
if (HistoryPhoto *media = dynamic_cast<HistoryPhoto*>(item->getMedia())) {
PhotoData *photo = media->photo();
if (!photo->full->isNull()) {
photo->full->forget();
QByteArray data = photo->full->savedData();
if (!data.isEmpty()) {
history.uploadMedia(data, PrepareDocument, item->history()->peer->id);
}
}
}
History *h = item->history();
bool wasLast = (h->lastMsg == item);
item->destroy();
if (wasLast && !h->lastMsg) historiesToCheck.insert(h, true);
}
}
for (QMap<History*, bool>::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) {
checkPeerHistory(i.key()->peer);
}
App::wnd()->hideLayer(true);
}
void MainWidget::onCancelResend() {
QMap<History*, bool> historiesToCheck;
QList<uint64> tmp = _resendImgRandomIds;
_resendImgRandomIds.clear();
for (int32 i = 0, l = tmp.size(); i < l; ++i) {
if (HistoryItem *item = App::histItemById(App::histItemByRandom(tmp.at(i)))) {
History *h = item->history();
bool wasLast = (h->lastMsg == item);
item->destroy();
if (wasLast && !h->lastMsg) historiesToCheck.insert(h, true);
}
}
for (QMap<History*, bool>::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) {
checkPeerHistory(i.key()->peer);
}
}
void MainWidget::onCacheBackground() {
const QPixmap &bg(*cChatBackground());
if (cTileBackground()) {
@ -2056,22 +1994,12 @@ void MainWidget::onSendFileCancel(const FileLoadResultPtr &file) {
history.cancelSendFile(file);
}
void MainWidget::confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo) {
history.confirmShareContact(ctrlShiftEnter, phone, fname, lname, replyTo);
void MainWidget::onShareContactConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter) {
history.confirmShareContact(phone, fname, lname, replyTo, ctrlShiftEnter);
}
void MainWidget::confirmSendImage(const ReadyLocalMedia &img) {
bool lastKeyboardUsed = history.lastForceReplyReplied(FullMsgId(peerToChannel(img.peer), img.replyTo));
history.confirmSendImage(img);
history.cancelReply(lastKeyboardUsed);
}
void MainWidget::confirmSendImageUncompressed(bool ctrlShiftEnter, MsgId replyTo) {
history.uploadConfirmImageUncompressed(ctrlShiftEnter, replyTo);
}
void MainWidget::cancelSendImage() {
history.cancelSendImage();
void MainWidget::onShareContactCancel() {
history.cancelShareContact();
}
void MainWidget::dialogsCancelled() {

View File

@ -267,11 +267,8 @@ public:
void onSendFileConfirm(const FileLoadResultPtr &file, bool ctrlShiftEnter);
void onSendFileCancel(const FileLoadResultPtr &file);
void confirmShareContact(bool ctrlShiftEnter, const QString &phone, const QString &fname, const QString &lname, MsgId replyTo);
void confirmSendImage(const ReadyLocalMedia &img);
void confirmSendImageUncompressed(bool ctrlShiftEnter, MsgId replyTo);
void cancelSendImage();
void onShareContactConfirm(const QString &phone, const QString &fname, const QString &lname, MsgId replyTo, bool ctrlShiftEnter);
void onShareContactCancel();
void destroyData();
void updateOnlineDisplayIn(int32 msecs);
@ -321,7 +318,6 @@ public:
void checkPeerHistory(PeerData *peer);
void checkedHistory(PeerData *peer, const MTPmessages_Messages &result);
bool sendPhotoFail(uint64 randomId, const RPCError &e);
bool sendMessageFail(const RPCError &error);
void forwardSelectedItems();
@ -478,9 +474,6 @@ public slots:
void onForwardCancel(QObject *obj = 0);
void onResendAsDocument();
void onCancelResend();
void onCacheBackground();
void onInviteImport();
@ -510,8 +503,6 @@ private:
QString failedFileName;
void loadFailed(mtpFileLoader *loader, bool started, const char *retrySlot);
QList<uint64> _resendImgRandomIds;
SelectedItemSet _toForward;
Text _toForwardFrom, _toForwardText;
int32 _toForwardNameVersion;