diff --git a/callwidget.cpp b/callwidget.cpp index bfb7806c983090c0d968aafc6d2ec204dc9bcb98..92d24f8c0937af182689da205ab476736b7e6c7b 100644 --- a/callwidget.cpp +++ b/callwidget.cpp @@ -23,10 +23,9 @@ #include "callwidget.h" #include "ui_callwidget.h" -#include <QScrollBar> -#include <QClipboard> -#include <QDesktopServices> #include <QComboBox> +#include <QDesktopServices> +#include <QScrollBar> #include <QWebEngineScript> #include <algorithm> @@ -43,15 +42,15 @@ #include "globalinstances.h" // client -#include "windowscontactbackend.h" -#include "globalsystemtray.h" +#include "animationhelpers.h" #include "conversationitemdelegate.h" -#include "pixbufmanipulator.h" -#include "settingskey.h" +#include "globalsystemtray.h" #include "lrcinstance.h" -#include "animationhelpers.h" -#include "ringthemeutils.h" #include "mainwindow.h" +#include "pixbufmanipulator.h" +#include "ringthemeutils.h" +#include "settingskey.h" +#include "windowscontactbackend.h" CallWidget::CallWidget(QWidget* parent) : NavWidget(parent), @@ -63,6 +62,7 @@ CallWidget::CallWidget(QWidget* parent) : using namespace lrc::api; QApplication::setEffectEnabled(Qt::UI_AnimateCombo, false); + clipboard_ = QApplication::clipboard(); QPixmap logo(":/images/logo-jami-standard-coul.png"); ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation)); @@ -202,12 +202,16 @@ CallWidget::CallWidget(QWidget* parent) : backToWelcomePage(); }); + connect(ui->messageView, SIGNAL(customContextMenuRequested(const QPoint&)), + this, SLOT(ShowContextMenu(const QPoint&))); + // set first view to welcome view ui->stackedWidget->setCurrentWidget(ui->welcomePage); ui->btnConversations->setChecked(true); // chat view ui->messageView->buildView(); + ui->messageView->setContextMenuPolicy(Qt::CustomContextMenu); // hide the call stack setCallPanelVisibility(false); @@ -351,7 +355,7 @@ CallWidget::setupSmartListContextMenu(const QPoint& pos) } }); // clear conversation - auto clearConversationAction = new QAction(tr("Clear conversation"), this); + auto clearConversationAction = new QAction(tr("Clear conversation"), this); menu.addAction(clearConversationAction); connect(clearConversationAction, &QAction::triggered, [convUid]() { @@ -1256,3 +1260,42 @@ CallWidget::setCallPanelVisibility(bool visible) ui->btnVideoCall->setVisible(!visible); ui->callStackWidget->setVisible(visible); } + +void +CallWidget::ShowContextMenu(const QPoint& pos) +{ + QPoint globalMousePos = QCursor::pos(); + const QMimeData* mimeData = clipboard_->mimeData(); + + QMenu contextMenu; + QAction action1("Copy", this); + QAction action2("Paste", this); + + contextMenu.addAction(&action1); + connect(&action1, SIGNAL(triggered()), this, SLOT(Copy())); + if (mimeData->hasText()) { + contextMenu.addAction(&action2); + connect(&action2, SIGNAL(triggered()), this, SLOT(Paste())); + } + + contextMenu.exec(globalMousePos); +} + +void +CallWidget::Paste() +{ + const QMimeData* mimeData = clipboard_->mimeData(); + if (mimeData->hasHtml()) { + ui->messageView->setMessagesContent(mimeData->text()); + } else if (mimeData->hasText()) { + ui->messageView->setMessagesContent(mimeData->text()); + } else { + ui->messageView->setMessagesContent(tr("Cannot display data")); + } +} + +void +CallWidget::Copy() +{ + ui->messageView->copySelectedText(clipboard_); +} diff --git a/callwidget.h b/callwidget.h index 5bcd57981a5738a69c822f4503aa006d6917c8d8..5a7d5afc659819d6e52cc56019d0d27564bf1e94 100644 --- a/callwidget.h +++ b/callwidget.h @@ -22,30 +22,31 @@ #pragma once -#include <QWidget> -#include <QVector> -#include <QString> -#include <QMenu> +#include <QClipboard> #include <QItemSelection> +#include <QMenu> #include <QMovie> +#include <QString> +#include <QVector> +#include <QWidget> #include "navwidget.h" #include "smartlistmodel.h" // old LRC -#include "video/renderer.h" -#include "video/previewmanager.h" #include "accountmodel.h" #include "media/textrecording.h" +#include "video/previewmanager.h" +#include "video/renderer.h" // new LRC -#include "globalinstances.h" -#include "api/newaccountmodel.h" -#include "api/conversationmodel.h" #include "api/account.h" #include "api/contact.h" #include "api/contactmodel.h" +#include "api/conversationmodel.h" +#include "api/newaccountmodel.h" #include "api/newcallmodel.h" +#include "globalinstances.h" class ConversationItemDelegate; class QPropertyAnimation; @@ -89,6 +90,9 @@ public slots: void slotToggleFullScreenClicked(); void slotVideoViewDestroyed(const std::string& callid); void update(); + void ShowContextMenu(const QPoint& pos); + void Paste(); + void Copy(); private slots: void on_acceptButton_clicked(); @@ -138,6 +142,7 @@ private: void setCallPanelVisibility(bool visible); QMenu* menu_; + QClipboard* clipboard_; Ui::CallWidget* ui; QMovie* miniSpinner_; diff --git a/messagewebview.cpp b/messagewebview.cpp index 2415f7882a4908ca0dfb21190c3c3a56953ec560..e3e7fa9c9f0f269c7c554a20053f4b322b85488f 100644 --- a/messagewebview.cpp +++ b/messagewebview.cpp @@ -21,27 +21,27 @@ #include "messagewebview.h" -#include <QScrollBar> -#include <QMouseEvent> #include <QDebug> -#include <QMenu> #include <QDesktopServices> #include <QFileDialog> +#include <QMenu> +#include <QMouseEvent> +#include <QScrollBar> +#include <QTimer> +#include <QWebChannel> #include <QWebEnginePage> +#include <QWebEngineProfile> #include <QWebEngineScript> #include <QWebEngineScriptCollection> #include <QWebEngineSettings> -#include <QWebEngineProfile> -#include <QWebChannel> -#include <QTimer> #include <ciso646> #include <fstream> +#include "lrcinstance.h" +#include "messagewebpage.h" #include "utils.h" #include "webchathelpers.h" -#include "messagewebpage.h" -#include "lrcinstance.h" MessageWebView::MessageWebView(QWidget *parent) : QWebEngineView(parent) @@ -106,6 +106,18 @@ MessageWebView::~MessageWebView() { } +void MessageWebView::setMessagesContent(QString text) +{ + page()->runJavaScript(QStringLiteral("document.getElementById('message').value = '%1'").arg(text)); +} + +void MessageWebView::copySelectedText(QClipboard* clipboard) +{ + page()->runJavaScript(QStringLiteral("copy_text_selected();"), [clipboard, this](const QVariant& v) { + clipboard->setText(v.toString()); + }); +} + void MessageWebView::buildView() { auto html = Utils::QByteArrayFromFile(":/web/chatview.html"); diff --git a/messagewebview.h b/messagewebview.h index 3c20e803b9c3b0f153aa7ff21e4d46ec95dc965e..86c39036500d89ac4cdb9959b2023d6963e37dfd 100644 --- a/messagewebview.h +++ b/messagewebview.h @@ -18,6 +18,7 @@ #pragma once +#include <QClipboard> #include <QDebug> #include <QWebEngineView> @@ -36,7 +37,7 @@ public: Q_INVOKABLE int openFile(const QString& arg); Q_INVOKABLE int acceptFile(const QString& arg); Q_INVOKABLE int refuseFile(const QString& arg); - Q_INVOKABLE int sendMessage(const QString & arg); + Q_INVOKABLE int sendMessage(const QString& arg); Q_INVOKABLE int sendFile(); Q_INVOKABLE int log(const QString& arg); Q_INVOKABLE int acceptInvitation(); @@ -55,8 +56,8 @@ public: void buildView(); - void insertStyleSheet(const QString &name, const QString &source); - void removeStyleSheet(const QString &name); + void insertStyleSheet(const QString& name, const QString& source); + void removeStyleSheet(const QString& name); void clear(); void setDisplayLinks(bool display); @@ -76,6 +77,8 @@ public: const std::string& contactUri = "", const std::string& contactId = ""); void setMessagesVisibility(bool visible); + void setMessagesContent(QString text); + void copySelectedText(QClipboard* clipboard); signals: void conversationRemoved(); diff --git a/web/chatview.css b/web/chatview.css index daedf44ab5c1f19349335c4824858cbbda668b28..2a6d69caddb7971d93743a53faa8b0a76c301660 100644 --- a/web/chatview.css +++ b/web/chatview.css @@ -54,7 +54,7 @@ body { background-color: var(--bg-color); padding-bottom: var(--messagebar-size); /* disable selection highlight because it looks very bad */ - -webkit-user-select: none; + -webkit-user-select: text; } diff --git a/web/chatview.js b/web/chatview.js index 917f4616e26cdcec90244eb1af5ad0e6f391ebdb..c7d6310e3546461951480644a96b46c6868be114 100644 --- a/web/chatview.js +++ b/web/chatview.js @@ -1608,3 +1608,12 @@ function setSenderImage(set_sender_image_object) invite_style.innerHTML = "." + invite_sender_image_id + " {content: url(data:image/png;base64," + sender_image + ");height: 48px;width: 48px;}" document.head.appendChild(invite_style) } + +/** + * Copy Mouse Selected Text and return it + */ +function copy_text_selected() { + var selObj = document.getSelection(); + var selectedText = selObj.toString(); + return selectedText; +}