diff --git a/Telegram/Resources/lang.strings b/Telegram/Resources/lang.strings index 60ad70b2b0..bfaa9b231a 100644 --- a/Telegram/Resources/lang.strings +++ b/Telegram/Resources/lang.strings @@ -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."; diff --git a/Telegram/SourceFiles/boxes/photosendbox.cpp b/Telegram/SourceFiles/boxes/photosendbox.cpp index 2b4e21a417..3236178060 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.cpp +++ b/Telegram/SourceFiles/boxes/photosendbox.cpp @@ -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(); } diff --git a/Telegram/SourceFiles/boxes/photosendbox.h b/Telegram/SourceFiles/boxes/photosendbox.h index 1dc2858740..597c4496ac 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.h +++ b/Telegram/SourceFiles/boxes/photosendbox.h @@ -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; }; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index f2f4db82cf..db544831da 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -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) { diff --git a/Telegram/SourceFiles/fileuploader.cpp b/Telegram/SourceFiles/fileuploader.cpp index 42f91b5ee8..57c2eac0f1 100644 --- a/Telegram/SourceFiles/fileuploader.cpp +++ b/Telegram/SourceFiles/fileuploader.cpp @@ -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) { diff --git a/Telegram/SourceFiles/fileuploader.h b/Telegram/SourceFiles/fileuploader.h index 0e44c67346..68476043fb 100644 --- a/Telegram/SourceFiles/fileuploader.h +++ b/Telegram/SourceFiles/fileuploader.h @@ -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; diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index c13040fede..297b6c0136 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -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(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(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(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); } } diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index e84c94663a..12cb3343b1 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -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; diff --git a/Telegram/SourceFiles/localimageloader.cpp b/Telegram/SourceFiles/localimageloader.cpp index 313294ef8a..ba9e7a0d04 100644 --- a/Telegram/SourceFiles/localimageloader.cpp +++ b/Telegram/SourceFiles/localimageloader.cpp @@ -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 photoSizes; - - QVector 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(); - } - } - } - } - } - 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(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(); - } - } - - 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(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()) +FileLoadTask::FileLoadTask(const QImage &image, PrepareMediaType type, const FileLoadTo &to, FileLoadForceConfirmType confirm, const QString &originalText) : _id(MTP::nonce()) , _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); } } diff --git a/Telegram/SourceFiles/localimageloader.h b/Telegram/SourceFiles/localimageloader.h index c8a94dae22..3b3770f9e1 100644 --- a/Telegram/SourceFiles/localimageloader.h +++ b/Telegram/SourceFiles/localimageloader.h @@ -86,72 +86,6 @@ struct ReadyLocalMedia { ReadyLocalMedia() : type(PrepareAuto) { // temp } }; -typedef QList 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 TaskPtr; +typedef QList 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 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 { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 6bd4a026c3..82d0175434 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -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 historiesToCheck; - QList 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(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::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) { - checkPeerHistory(i.key()->peer); - } - App::wnd()->hideLayer(true); -} - -void MainWidget::onCancelResend() { - QMap historiesToCheck; - QList 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::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() { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index b4acf68eaa..599f6ab97b 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -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 _resendImgRandomIds; - SelectedItemSet _toForward; Text _toForwardFrom, _toForwardText; int32 _toForwardNameVersion;