Skip to content
This repository has been archived by the owner on Oct 17, 2019. It is now read-only.

Implement #132: Support pasting images into room #138

Closed
wants to merge 5 commits into from

Conversation

christarazi
Copy link
Contributor

Implements #132 to allow pasting of images using ctrl-v.

Copy link
Contributor

@Ralith Ralith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the other issues I highlighted, I don't see any graceful handling for the case where a user attempts to enter both text and imagery in the same message. It looks like text entered alongside an image is accepted and then silently discarded, which is a bad user experience.

@@ -93,12 +97,50 @@ FilteredTextEdit::keyPressEvent(QKeyEvent *event)
}
break;
}
case Qt::Key_V: {
if (event->modifiers() == Qt::ControlModifier) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding this is incorrect. You cannot make assumptions about what keybind any given system uses to express "paste." Try using QKeySequence::Copy instead.

Copy link
Contributor

@Ralith Ralith Nov 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On further review, given that Qt handles MIME clipboards in the first place, it's actually not obvious to me that handling pasting by hand like this is even necessary at all, given the other changes in this PR. If it truly is, some comments explaining why Qt's default behavior is inadequate would be nice.

Copy link
Contributor Author

@christarazi christarazi Nov 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure of what you mean. If you mean, that Qt has built in support out-of-the-box for pasting images into a QTextEdit, then I have not seen any document which suggests that. The fact that QTextEdit::insertFromMimeData and QTextEdit::canInsertFromMimeData exist suggest that it does not have built in support. However, this is just an educated guess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to guess. What happens if you disable this hardcoding but retain the overrides to those methods?

Copy link
Contributor Author

@christarazi christarazi Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. I removed the explicit call to insertFromMimeData() (the entire case in the switch statement), and kept just the overrides. It still works.

Copy link
Contributor Author

@christarazi christarazi Nov 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary hardcoded handling of paste fixed in 41b887b and 0e178cc

QImage img = qvariant_cast<QImage>(source->imageData());
pastedImagePath_ = QDir::tempPath() + '/' + "nheko_pasted_img.png";

// Save image into temporary path to be loaded later.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no reason for this to hit disk, and doing so introduces a number of bugs. Leave the image in memory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I write to disk is because MatrixClient::uploadImage() takes in a QString that represents a file path to an image. This means I would have to overload uploadImage or create a new function which accepts an image from memory. If you think that is worth doing, I will implement it.

Copy link
Contributor

@Ralith Ralith Nov 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably refactor uploadImage to accept data from arbitrary sources, e.g. by taking a QIODevice. This change to the PR is necessary for a number of reasons; most immediately, the current code introduces system-global state, which makes it unsafe to have multiple instances of the class even in entirely different processes. It is also poor behavior to silently re-encode submitted images.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll create a new pull request with the requested changes.

@Ralith
Copy link
Contributor

Ralith commented Nov 26, 2017

Another concern is the handling of pastes that include both image(s) and text concatenated in a single piece of MIME data, along with a possible alternative plaintext representation.

It's worth note that Matrix can support this type of mixed-content message by placing the alternative plaintext in body and using formatted_body with img tags that reference mxc URIs to encode the mixed form, although no existing client generates such messages automatically. I believe Riot, at least, will nonetheless render such messages as expected.

@christarazi
Copy link
Contributor Author

christarazi commented Nov 27, 2017

Another concern is the handling of pastes that include both image(s) and text concatenated in a single piece of MIME data, along with a possible alternative plaintext representation.

It's worth note that Matrix can support this type of mixed-content message by placing the alternative plaintext in body and using formatted_body with img tags that reference mxc URIs to encode the mixed form, although no existing client generates such messages automatically. I believe Riot, at least, will nonetheless render such messages as expected.

@Ralith On my local branch, I made the change to allow both images and text in the same message. I did this by checking if isImage_ is true, and if so, then removing the encoded image (encoded as U+FFFC) from the text, and allowing the existing code to take care of the rest.

Edit:

Fixed in af238f7.

@mujx
Copy link
Owner

mujx commented Nov 27, 2017

How exactly I can use this feature? If I copy-paste an image into the text field I just get the file path of that image and nothing happens when I hit enter.

@christarazi
Copy link
Contributor Author

christarazi commented Nov 28, 2017

How exactly I can use this feature? If I copy-paste an image into the text field I just get the file path of that image and nothing happens when I hit enter.

Didn't realize that X11 treats copying files differently in regards to setting the MIME type. I was testing my implementation by right-clicking an image in my browser and hitting "Copy image". This is now fixed in 4e8034c.

@christarazi
Copy link
Contributor Author

Now that I think of it, we might as well handle all files that are pasted in the text box. The commit in 4e8034c only handles pasting images, but it should be a trivial change to allow pasting of any file.

@mujx
Copy link
Owner

mujx commented Nov 28, 2017

This also doesn't work on macOS. Instead of the actual image a generic image placeholder is sent.

Another issue is that the image is rendered in the text field and only a thin slice of it is visible which makes it a bad user experience. It would be better to show a confirmation popup to send the image or file (like Telegram does).

I'm against mixing images and text in the same messages cause it would be quite difficult to implement and it doesn't have any real benefit in my opinion.

@christarazi
Copy link
Contributor Author

christarazi commented Nov 28, 2017 via email

@christarazi
Copy link
Contributor Author

christarazi commented Nov 29, 2017 via email

@mujx
Copy link
Owner

mujx commented Nov 29, 2017

@christarazi I could find a fix for mac later, it's not super critical. The important part is to have that popup when a pasted file or image is detected and possibly allow the user to edit the name of the file before sending it, so nothing would be pasted into the text field.

Copy link
Contributor

@Ralith Ralith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @mujx that (opening a dialog for) sending pasted (or dropped) files immediately makes more sense than handling them as if they were part of the input text, at least so long as nheko doesn't have advanced formatting capabilities.

@@ -229,6 +280,9 @@ TextInputWidget::TextInputWidget(QWidget *parent)
connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
connect(input_, &FilteredTextEdit::message, this, &TextInputWidget::sendTextMessage);
connect(input_, &FilteredTextEdit::command, this, &TextInputWidget::command);
connect(input_, &FilteredTextEdit::image, this, [=](QString name) {
emit uploadImage(name);
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this can be written connect(input_, &FilteredTextEdit::image, this, uploadImage)

@christarazi
Copy link
Contributor Author

I've created a new PR (#180) which adds a preview dialog for pasting images and also modifies the MatrixClient::upload*() members to take in a QIODevice instead of a QString.

@christarazi christarazi deleted the paste-img branch February 19, 2018 05:37
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants