feature: paste image in chat #51
@ -20,6 +20,7 @@
|
|||||||
#include "ui_conversation.h"
|
#include "ui_conversation.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QClipboard>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@ -27,6 +28,9 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <QAbstractTextDocumentLayout>
|
#include <QAbstractTextDocumentLayout>
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QTemporaryFile>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, const QString pJid, const QString pRes, QWidget* parent):
|
Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el, const QString pJid, const QString pRes, QWidget* parent):
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
@ -47,6 +51,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
|
|||||||
delegate(new MessageDelegate(this)),
|
delegate(new MessageDelegate(this)),
|
||||||
manualSliderChange(false),
|
manualSliderChange(false),
|
||||||
tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1),
|
tsb(QApplication::style()->styleHint(QStyle::SH_ScrollBar_Transient) == 1),
|
||||||
|
pasteImageAction(nullptr),
|
||||||
shadow(10, 1, Qt::black, this),
|
shadow(10, 1, Qt::black, this),
|
||||||
contextMenu(new QMenu())
|
contextMenu(new QMenu())
|
||||||
{
|
{
|
||||||
@ -75,6 +80,7 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
|
|||||||
statusLabel = m_ui->statusLabel;
|
statusLabel = m_ui->statusLabel;
|
||||||
|
|
||||||
connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed);
|
connect(&ker, &KeyEnterReceiver::enterPressed, this, &Conversation::onEnterPressed);
|
||||||
|
connect(&ker, &KeyEnterReceiver::imagePasted, this, &Conversation::onImagePasted);
|
||||||
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
|
connect(m_ui->sendButton, &QPushButton::clicked, this, &Conversation::onEnterPressed);
|
||||||
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
|
connect(m_ui->attachButton, &QPushButton::clicked, this, &Conversation::onAttach);
|
||||||
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
|
connect(m_ui->clearButton, &QPushButton::clicked, this, &Conversation::onClearButton);
|
||||||
@ -82,7 +88,20 @@ Conversation::Conversation(bool muc, Models::Account* acc, Models::Element* el,
|
|||||||
this, &Conversation::onTextEditDocSizeChanged);
|
this, &Conversation::onTextEditDocSizeChanged);
|
||||||
|
|
||||||
m_ui->messageEditor->installEventFilter(&ker);
|
m_ui->messageEditor->installEventFilter(&ker);
|
||||||
|
|
||||||
|
QAction* pasteImageAction = new QAction(tr("Paste Image"), this);
|
||||||
blue marked this conversation as resolved
|
|||||||
|
connect(pasteImageAction, &QAction::triggered, this, &Conversation::onImagePasted);
|
||||||
|
|
||||||
|
m_ui->messageEditor->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(m_ui->messageEditor, &QTextEdit::customContextMenuRequested, this, [this, pasteImageAction](const QPoint &pos) {
|
||||||
|
pasteImageAction->setEnabled(Conversation::checkClipboardImage());
|
||||||
|
|
||||||
|
QMenu *editorMenu = m_ui->messageEditor->createStandardContextMenu();
|
||||||
|
editorMenu->addSeparator();
|
||||||
|
editorMenu->addAction(pasteImageAction);
|
||||||
|
|
||||||
|
editorMenu->exec(this->m_ui->messageEditor->mapToGlobal(pos));
|
||||||
|
});
|
||||||
|
|
||||||
//line->setAutoFillBackground(false);
|
//line->setAutoFillBackground(false);
|
||||||
//if (testAttribute(Qt::WA_TranslucentBackground)) {
|
//if (testAttribute(Qt::WA_TranslucentBackground)) {
|
||||||
@ -183,10 +202,20 @@ bool KeyEnterReceiver::eventFilter(QObject* obj, QEvent* event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (k == Qt::Key_V && key->modifiers() & Qt::CTRL) {
|
||||||
|
if (Conversation::checkClipboardImage()) {
|
||||||
|
emit imagePasted();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return QObject::eventFilter(obj, event);
|
return QObject::eventFilter(obj, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Conversation::checkClipboardImage() {
|
||||||
|
return !QApplication::clipboard()->image().isNull();
|
||||||
|
}
|
||||||
|
|
||||||
QString Conversation::getPalResource() const
|
QString Conversation::getPalResource() const
|
||||||
{
|
{
|
||||||
return activePalResource;
|
return activePalResource;
|
||||||
@ -218,6 +247,20 @@ void Conversation::onEnterPressed()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Conversation::onImagePasted()
|
||||||
|
{
|
||||||
|
QImage image = QApplication::clipboard()->image();
|
||||||
|
if (image.isNull()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + QStringLiteral("/squawk_img_attach_XXXXXX.png"), QApplication::instance());
|
||||||
blue
commented
Interestring solution... Interestring solution...
I actually was thinking of it, but was more into may be saving it into downloads folder, for the next time. Like this way at somepoint the image is not going to be accesible, so, we're going to be forced to download it to see it.
Dunno, i really have mixed feelings about my way, what do you think?
shunf4
commented
I agree with you. Placing the pasted image into downloads folder is better. Or putting it to temp folder, then moving it to downloads folder if it is sent successfully? I agree with you. Placing the pasted image into downloads folder is better.
Or putting it to temp folder, then moving it to downloads folder if it is sent successfully?
blue
commented
Yeah, that would do! But if you will move the image on successfull send you're going to need to update the path to the image in databases after the image is moved, I hope I've done that handler... Yeah, that would do! But if you will move the image on successfull send you're going to need to update the path to the image in databases after the image is moved, I hope I've done that handler...
shunf4
commented
Done in The file is copied (rather than moved) because it might still be used by Done in https://git.macaw.me/blue/squawk/commit/39f2f3d975a1ce38144ef1992506416a934e5005 .
The file is copied (rather than moved) because it might still be used by `QImageReader` in message preview widget.
|
|||||||
|
tempFile->open();
|
||||||
|
image.save(tempFile, "PNG");
|
||||||
|
tempFile->close();
|
||||||
|
qDebug() << "image on paste temp file: " << tempFile->fileName();
|
||||||
|
addAttachedFile(tempFile->fileName());
|
||||||
|
}
|
||||||
|
|
||||||
void Conversation::onAttach()
|
void Conversation::onAttach()
|
||||||
{
|
{
|
||||||
QFileDialog* d = new QFileDialog(this, tr("Chose a file to send"));
|
QFileDialog* d = new QFileDialog(this, tr("Chose a file to send"));
|
||||||
|
@ -60,6 +60,7 @@ protected:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void enterPressed();
|
void enterPressed();
|
||||||
|
void imagePasted();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Conversation : public QWidget
|
class Conversation : public QWidget
|
||||||
@ -77,6 +78,7 @@ public:
|
|||||||
void setPalResource(const QString& res);
|
void setPalResource(const QString& res);
|
||||||
virtual void setAvatar(const QString& path);
|
virtual void setAvatar(const QString& path);
|
||||||
void setFeedFrames(bool top, bool right, bool bottom, bool left);
|
void setFeedFrames(bool top, bool right, bool bottom, bool left);
|
||||||
|
static bool checkClipboardImage();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendMessage(const Shared::Message& message);
|
void sendMessage(const Shared::Message& message);
|
||||||
@ -102,6 +104,7 @@ protected:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onEnterPressed();
|
void onEnterPressed();
|
||||||
|
void onImagePasted();
|
||||||
void onAttach();
|
void onAttach();
|
||||||
void onFileSelected();
|
void onFileSelected();
|
||||||
void onBadgeClose();
|
void onBadgeClose();
|
||||||
@ -133,6 +136,8 @@ protected:
|
|||||||
bool manualSliderChange;
|
bool manualSliderChange;
|
||||||
bool tsb; //transient scroll bars
|
bool tsb; //transient scroll bars
|
||||||
|
|
||||||
|
QAction* pasteImageAction;
|
||||||
|
|
||||||
ShadowOverlay shadow;
|
ShadowOverlay shadow;
|
||||||
QMenu* contextMenu;
|
QMenu* contextMenu;
|
||||||
};
|
};
|
||||||
|
Do you mind if we better move it to initialization block? Cuz, since you declare here that variable again as QAction* it might be even considered like another variable rather than that one declared as a property...
How about this change?
52551c1ce0
That's good, thank you!