Merge pull request #2715 from thunder2/imageutil

Moved RSTextBrowser::checkImage to ImageUtil for use in MimeTextEdit
This commit is contained in:
csoler 2023-04-19 20:46:37 +02:00 committed by GitHub
commit 1ebff07067
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 121 additions and 67 deletions

View File

@ -627,7 +627,7 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
QString toolTipText = ui->textBrowser->anchorForPosition(helpEvent->pos());
if (toolTipText.isEmpty() && !ui->textBrowser->getShowImages()){
QString imageStr;
if (ui->textBrowser->checkImage(helpEvent->pos(), imageStr)) {
if (ImageUtil::checkImage(ui->textBrowser, helpEvent->pos(), imageStr)) {
toolTipText = imageStr;
}
} else if (toolTipText.startsWith(PERSONID)){
@ -1158,7 +1158,7 @@ void ChatWidget::contextMenuTextBrowser(QPoint point)
contextMnu->addAction(ui->actionQuote);
contextMnu->addAction(ui->actionDropPlacemark);
if(ui->textBrowser->checkImage(point))
if(ImageUtil::checkImage(ui->textBrowser, point))
{
if (! ui->textBrowser->getShowImages())
contextMnu->addAction(ui->actionShow_Hidden_Images);

View File

@ -32,6 +32,7 @@
#include "MimeTextEdit.h"
#include "util/HandleRichText.h"
#include "gui/RetroShareLink.h"
#include "util/imageutil.h"
#include <retroshare/rspeers.h>
@ -246,6 +247,18 @@ void MimeTextEdit::contextMenuEvent(QContextMenuEvent *e)
QMenu *contextMenu = createStandardContextMenu(e->pos());
if (ImageUtil::checkImage(this, e->pos())) {
contextMenu->addSeparator();
QAction *a = contextMenu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage()));
a->setData(e->pos());
a = contextMenu->addAction( tr("Copy image"), this, SLOT(copyImage()));
a->setData(e->pos());
contextMenu->addSeparator();
}
/* Add actions for pasting links */
contextMenu->addAction( tr("Paste as plain text"), this, SLOT(pastePlainText()));
QAction *spoilerAction = contextMenu->addAction(tr("Spoiler"), this, SLOT(spoiler()));
@ -292,3 +305,27 @@ void MimeTextEdit::spoiler()
{
RsHtml::insertSpoilerText(this->textCursor());
}
void MimeTextEdit::saveImage()
{
QAction *action = dynamic_cast<QAction*>(sender()) ;
if (!action) {
return;
}
QPoint point = action->data().toPoint();
QTextCursor cursor = cursorForPosition(point);
ImageUtil::extractImage(window(), cursor);
}
void MimeTextEdit::copyImage()
{
QAction *action = dynamic_cast<QAction*>(sender()) ;
if (!action) {
return;
}
QPoint point = action->data().toPoint();
QTextCursor cursor = cursorForPosition(point);
ImageUtil::copyImage(window(), cursor);
}

View File

@ -75,6 +75,8 @@ private slots:
void pasteOwnCertificateLink();
void pastePlainText();
void spoiler();
void saveImage();
void copyImage();
private:
QString textUnderCursor() const;

View File

@ -234,64 +234,6 @@ void RSTextBrowser::activateLinkClick(bool active)
mLinkClickActive = active;
}
/**
* @brief RSTextBrowser::checkImage
* @param pos where to check if image is shown in viewport coordinate
* @param imageStr return html source of cursor
* @return True if an image is under cursor
*/
bool RSTextBrowser::checkImage(QPoint pos, QString &imageStr)
{
//Get text cursor under pos. But if pos is under text browser end line this return last cursor.
QTextCursor cursor = cursorForPosition(pos);
//First get rect of cursor (could be at left or right of image)
QRect cursorRectStart = cursorRect(cursor);
//Second get text
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);//To get character just before
QRect cursorRectLeft = cursorRect(cursor);
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
QRect cursorRectRight = cursorRect(cursor);
imageStr = cursor.selection().toHtml();
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
mCursorRectStart = cursorRectStart;
mCursorRectLeft = cursorRectLeft;
mCursorRectRight = cursorRectRight;
std::cerr << "cursorRect LTRB :" << cursorRectStart.left() << ";" << cursorRectStart.top() << ";" << cursorRectStart.right() << ";" << cursorRectStart.bottom() << std::endl;
std::cerr << "cursorRectLeft :" << cursorRectLeft.left() << ";" << cursorRectLeft.top() << ";" << cursorRectLeft.right() << ";" << cursorRectLeft.bottom() << std::endl;
std::cerr << "cursorRectRight :" << cursorRectRight.left() << ";" << cursorRectRight.top() << ";" << cursorRectRight.right() << ";" << cursorRectRight.bottom() << std::endl;
std::cerr << "pos XY :" << pos.x() << ";" << pos.y() << std::endl;
#endif
QRect cursorRectEnd = cursorRectStart;
//Finally set left with right of precedent character.
if (cursorRectEnd.top() < cursorRectLeft.bottom())
{
cursorRectEnd.setLeft(cursorRectLeft.right());
} else {
//Image on new line
cursorRectEnd.setLeft(0);
}
//And set Right with left of next character.
if (cursorRectEnd.bottom() > cursorRectRight.top())
{
cursorRectEnd.setRight(cursorRectRight.left());
} else {
//New line after Image.
}
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
mCursorRectEnd = cursorRectEnd;
std::cerr << "final cursorRect:" << cursorRectEnd.left() << ";" << cursorRectEnd.top() << ";" << cursorRectEnd.right() << ";" << cursorRectEnd.bottom() << std::endl;
viewport()->update();
#endif
//If pos is on text rect
if (cursorRectEnd.contains(pos))
{
return imageStr.indexOf("base64,") != -1;
}
return false;
}
/**
* @brief RSTextBrowser::anchorForPosition Replace anchorAt that doesn't works as expected.
* @param pos Where to get anchor from text
@ -351,16 +293,27 @@ QMenu *RSTextBrowser::createStandardContextMenuFromPoint(const QPoint &widgetPos
QAction *a = menu->addAction(FilesDefs::getIconFromQtResourcePath("://icons/textedit/code.png"), tr("View &Source"), this, SLOT(viewSource()));
a->setEnabled(!this->document()->isEmpty());
if (checkImage(widgetPos)) {
if (ImageUtil::checkImage(this, widgetPos
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
, &mCursorRectStart, &mCursorRectLeft, &mCursorRectRight, &mCursorRectEnd
#endif
)) {
a = menu->addAction(FilesDefs::getIconFromQtResourcePath(":/images/document_save.png"), tr("Save image"), this, SLOT(saveImage()));
a->setData(widgetPos);
}
if (checkImage(widgetPos)) {
a = menu->addAction( tr("Copy image"), this, SLOT(copyImage()));
a->setData(widgetPos);
}
#ifdef RSTEXTBROWSER_CHECKIMAGE_DEBUG
std::cerr << "cursorRect LTRB :" << mCursorRectStart.left() << ";" << mCursorRectStart.top() << ";" << mCursorRectStart.right() << ";" << mCursorRectStart.bottom() << std::endl;
std::cerr << "cursorRectLeft :" << mCursorRectLeft.left() << ";" << mCursorRectLeft.top() << ";" << mCursorRectLeft.right() << ";" << mCursorRectLeft.bottom() << std::endl;
std::cerr << "cursorRectRight :" << mCursorRectRight.left() << ";" << mCursorRectRight.top() << ";" << mCursorRectRight.right() << ";" << mCursorRectRight.bottom() << std::endl;
std::cerr << "pos XY :" << widgetPos.x() << ";" << widgetPos.y() << std::endl;
std::cerr << "final cursorRect:" << mCursorRectEnd.left() << ";" << mCursorRectEnd.top() << ";" << mCursorRectEnd.right() << ";" << mCursorRectEnd.bottom() << std::endl;
viewport()->update();
#endif
return menu;
}

View File

@ -45,8 +45,6 @@ public:
void setImageBlockWidget(RSImageBlockWidget *widget);
void resetImagesStatus(bool load);
QPixmap getBlockedImage();
bool checkImage(QPoint pos, QString &imageStr);
bool checkImage(QPoint pos) {QString imageStr; return checkImage(pos, imageStr); }
QString anchorForPosition(const QPoint &pos) const;
// Add QAction to context menu (action won't be deleted)

View File

@ -23,6 +23,8 @@
#include "util/rstime.h"
#include <QApplication>
#include <QWidget>
#include <QTextEdit>
#include <QByteArray>
#include <QImage>
#include <QClipboard>
@ -39,6 +41,64 @@
ImageUtil::ImageUtil() {}
bool ImageUtil::checkImage(const QTextEdit *edit, const QPoint &pos, QRect *cursorRectStartOut, QRect *cursorRectLeftOut, QRect *cursorRectRightOut, QRect *cursorRectEndOut)
{
QString imageStr;
return checkImage(edit, pos, imageStr, cursorRectStartOut, cursorRectLeftOut, cursorRectRightOut, cursorRectEndOut);
}
bool ImageUtil::checkImage(const QTextEdit *edit, const QPoint &pos, QString &imageStr, QRect *cursorRectStartOut, QRect *cursorRectLeftOut, QRect *cursorRectRightOut, QRect *cursorRectEndOut)
{
//Get text cursor under pos. But if pos is under text browser end line this return last cursor.
QTextCursor cursor = edit->cursorForPosition(pos);
//First get rect of cursor (could be at left or right of image)
QRect cursorRectStart = edit->cursorRect(cursor);
//Second get text
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);//To get character just before
QRect cursorRectLeft = edit->cursorRect(cursor);
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);
QRect cursorRectRight = edit->cursorRect(cursor);
imageStr = cursor.selection().toHtml();
if (cursorRectStartOut) {
*cursorRectStartOut = cursorRectStart;
}
if (cursorRectLeftOut) {
*cursorRectLeftOut = cursorRectLeft;
}
if (cursorRectRightOut) {
*cursorRectRightOut = cursorRectRight;
}
QRect cursorRectEnd = cursorRectStart;
//Finally set left with right of precedent character.
if (cursorRectEnd.top() < cursorRectLeft.bottom())
{
cursorRectEnd.setLeft(cursorRectLeft.right());
} else {
//Image on new line
cursorRectEnd.setLeft(0);
}
//And set Right with left of next character.
if (cursorRectEnd.bottom() > cursorRectRight.top())
{
cursorRectEnd.setRight(cursorRectRight.left());
} else {
//New line after Image.
}
if (cursorRectEndOut) {
*cursorRectEndOut = cursorRectEnd;
}
//If pos is on text rect
if (cursorRectEnd.contains(pos))
{
return imageStr.indexOf("base64,") != -1;
}
return false;
}
void ImageUtil::extractImage(QWidget *window, QTextCursor cursor, QString file)
{
cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor, 1);

View File

@ -22,15 +22,19 @@
#define IMAGEUTIL_H
#include <QTextCursor>
#include <QWidget>
#include <QByteArray>
#include <qiterator.h>
class QWidget;
class QTextEdit;
class QByteArray;
class ImageUtil
{
public:
ImageUtil();
static bool checkImage(const QTextEdit *edit, const QPoint &pos, QRect *cursorRectStartOut = NULL, QRect *cursorRectLeftOut = NULL, QRect *cursorRectRightOut = NULL, QRect *cursorRectEndOut = NULL);
static bool checkImage(const QTextEdit *edit, const QPoint &pos, QString &imageStr, QRect *cursorRectStartOut = NULL, QRect *cursorRectLeftOut = NULL, QRect *cursorRectRightOut = NULL, QRect *cursorRectEndOut = NULL);
static void extractImage(QWidget *window, QTextCursor cursor, QString file = "");
static void copyImage(QWidget *window, QTextCursor cursor);
static bool optimizeSizeHtml(QString &html, const QImage& original, QImage &optimized, int maxPixels = -1, int maxBytes = -1);