Added ability to edit media via clipboard and remoteContent.

- Moved thumb updating to updateEditPreview() method.
 - Added _viaRemoteContent var to check when we use remoteContent.
 - Added setMimeDataHook to handle clipboard content.
This commit is contained in:
23rd 2019-04-01 22:09:14 +03:00 committed by John Preston
parent 94964c35ce
commit 4988d21819
2 changed files with 158 additions and 66 deletions

View File

@ -333,34 +333,31 @@ void EditCaptionBox::clipCallback(Media::Clip::Notification notification) {
}
}
void EditCaptionBox::createEditMediaButton() {
const auto callback = [=](const FileDialog::OpenResult &result) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
return;
}
if (!result.paths.isEmpty()) {
const auto filePath = result.paths.front();
_newMediaPath = filePath;
_preparedList = Storage::PrepareMediaList(
QStringList(_newMediaPath),
st::sendMediaPreviewSize);
void EditCaptionBox::updateEditPreview() {
using Info = FileMediaInformation;
const auto file = &_preparedList.files.front();
const auto fileMedia = &file->information->media;
const auto fileinfo = QFileInfo(_newMediaPath);
const auto filename = fileinfo.fileName();
const auto mimeType = Core::MimeTypeForFile(fileinfo).name();
if (!_isNotAlbum) {
// This check only for users, who chose not valid file with absolute path.
if (!fileIsValidForAlbum(filename, Core::MimeTypeForFile(fileinfo).name())) {
if ((!_newMediaPath.isEmpty()
&& !fileIsValidForAlbum(filename, mimeType))
// And for users, who send file via remoteContent.
|| _viaRemoteContent) {
_newMediaPath = QString();
_preparedList.files.clear();
return;
}
}
_isImage = fileIsImage(filename, Core::MimeTypeForFile(fileinfo).name());
if (!_newMediaPath.isEmpty()) {
_isImage = fileIsImage(filename, mimeType);
}
_isAudio = false;
_animated = false;
_photo = false;
@ -369,31 +366,34 @@ void EditCaptionBox::createEditMediaButton() {
_thumbw = _thumbh = _thumbx = 0;
_gifw = _gifh = _gifx = 0;
_wayWrap->toggle(_isImage && _isNotAlbum, anim::type::instant);
using Info = FileMediaInformation;
if (const auto image = base::get_if<Info::Image>(fileMedia)
&& _isImage) {
if (const auto image = base::get_if<Info::Image>(fileMedia)) {
_photo = true;
} else if (const auto video =
base::get_if<Info::Video>(fileMedia)) {
_isImage = true;
} else if (const auto video = base::get_if<Info::Video>(fileMedia)) {
_animated = true;
// Never edit video as gif.
video->isGifv = false;
} else {
auto nameString = filename;
if (const auto song =
base::get_if<Info::Song>(fileMedia)) {
if (const auto song = base::get_if<Info::Song>(fileMedia)) {
nameString = DocumentData::ComposeNameString(
filename,
song->title,
song->performer);
_isAudio = true;
}
setName(nameString, fileinfo.size());
setName(
nameString.isEmpty()
? QString("file")
: nameString,
fileinfo.size()
? fileinfo.size()
: _preparedList.files.front().content.size());
_doc = true;
}
_wayWrap->toggle(_isImage && _isNotAlbum, anim::type::instant);
if (!_doc) {
_thumb = App::pixmapFromImageInPlace(
file->preview.scaled(st::sendMediaPreviewSize,
@ -405,6 +405,29 @@ void EditCaptionBox::createEditMediaButton() {
}
captionResized();
}
void EditCaptionBox::createEditMediaButton() {
const auto callback = [=](FileDialog::OpenResult &&result) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
return;
}
_viaRemoteContent = !result.remoteContent.isEmpty();
if (!result.remoteContent.isEmpty()) {
_newMediaPath = QString();
_preparedList = Storage::PrepareMediaFromImage(
Media::Clip::PrepareForSending(QString(), result.remoteContent).thumbnail,
std::move(result.remoteContent),
st::sendMediaPreviewSize);
} else if (!result.paths.isEmpty()) {
_newMediaPath = result.paths.front();
_preparedList = Storage::PrepareMediaList(
QStringList(_newMediaPath),
st::sendMediaPreviewSize);
} else {
return;
}
updateEditPreview();
};
const auto buttonCallback = [=] {
@ -438,6 +461,30 @@ void EditCaptionBox::prepare() {
connect(_field, &Ui::InputField::submitted, [=] { save(); });
connect(_field, &Ui::InputField::cancelled, [=] { closeBox(); });
connect(_field, &Ui::InputField::resized, [=] { captionResized(); });
_field->setMimeDataHook([=](
not_null<const QMimeData*> data,
Ui::InputField::MimeAction action) {
if (action == Ui::InputField::MimeAction::Check) {
if (data->hasImage()) {
const auto image = qvariant_cast<QImage>(data->imageData());
if (!image.isNull()) {
return true;
}
}
if (const auto urls = data->urls(); !urls.empty()) {
if (ranges::find_if(
urls,
[](const QUrl &url) { return !url.isLocalFile(); }
) == urls.end()) {
return true;
}
}
return data->hasText();
} else if (action == Ui::InputField::MimeAction::Insert) {
return fileFromClipboard(data);
}
Unexpected("action in MimeData hook.");
});
Ui::Emoji::SuggestionsController::Init(
getDelegate()->outerContainer(),
_field);
@ -449,6 +496,48 @@ void EditCaptionBox::prepare() {
_field->setTextCursor(cursor);
}
bool EditCaptionBox::fileFromClipboard(not_null<const QMimeData*> data) {
auto list = [&] {
auto url = QList<QUrl>();
auto canAddUrl = false;
// When we edit media, we need only 1 file.
if (data->hasUrls()) {
const auto first = data->urls().front();
url.push_front(first);
canAddUrl = first.isLocalFile();
}
auto result = canAddUrl
? Storage::PrepareMediaList(url, st::sendMediaPreviewSize)
: Storage::PreparedList(
Storage::PreparedList::Error::EmptyFile,
QString());
if (result.error == Storage::PreparedList::Error::None) {
return result;
} else if (data->hasImage()) {
auto image = qvariant_cast<QImage>(data->imageData());
if (!image.isNull()) {
_isImage = true;
_photo = true;
return Storage::PrepareMediaFromImage(
std::move(image),
QByteArray(),
st::sendMediaPreviewSize);
}
}
return result;
}();
_preparedList = std::move(list);
_newMediaPath = _preparedList.files.empty()
? QString()
: _preparedList.files.front().path;
if (_preparedList.files.empty()) {
return false;
}
_viaRemoteContent = false;
updateEditPreview();
return true;
}
void EditCaptionBox::captionResized() {
updateBoxSize();
resizeEvent(0);
@ -658,7 +747,7 @@ void EditCaptionBox::save() {
flags |= MTPmessages_EditMessage::Flag::f_entities;
}
if (!_newMediaPath.isEmpty()) {
if (!_preparedList.files.empty()) {
App::main()->setEditMedia(item->fullId());
const auto textWithTags = _field->getTextWithAppliedMarkdown();
auto sending = TextWithEntities{

View File

@ -65,6 +65,8 @@ private:
bool saveFail(const RPCError &error);
void setName(QString nameString, qint64 size);
bool fileFromClipboard(not_null<const QMimeData*> data);
void updateEditPreview();
int errorTopSkip() const;
@ -109,7 +111,8 @@ private:
Ui::SlideWrap<Ui::RpWidget> *_wayWrap = nullptr;
QString _newMediaPath;
bool _isAllowedEditMedia = false;
bool _isNotAlbum;
bool _isNotAlbum = true;
bool _viaRemoteContent = false;
rpl::event_stream<> _editMediaClicks;
QString _error;