#include "vwebview.h" #include #include #include #include #include #include #include #include #include #include #include "vfile.h" #include "utils/vclipboardutils.h" #include "utils/viconutils.h" // We set the property of the clipboard to mark that the URL copied in the // clipboard has been altered. static const QString c_ClipboardPropertyMark = "CopiedImageURLAltered"; VWebView::VWebView(VFile *p_file, QWidget *p_parent) : QWebEngineView(p_parent), m_file(p_file), m_actionHooked(false) { setAcceptDrops(false); } void VWebView::contextMenuEvent(QContextMenuEvent *p_event) { #if defined(Q_OS_WIN) if (!m_actionHooked) { m_actionHooked = true; // "Copy Image URL" action will put the encoded URL to the clipboard as text // and the URL as URLs. If the URL contains Chinese, OneNote or Word could not // recognize it. // We need to change it to only-space-encoded text. QAction *copyImageUrlAct = pageAction(QWebEnginePage::CopyImageUrlToClipboard); connect(copyImageUrlAct, &QAction::triggered, this, [this](){ // To avoid failure of setting clipboard mime data. QCoreApplication::processEvents(); QClipboard *clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(); clipboard->setProperty(c_ClipboardPropertyMark.toLatin1(), false); if (clipboard->ownsClipboard() && mimeData->hasText() && mimeData->hasUrls()) { QString text = mimeData->text(); QList urls = mimeData->urls(); if (urls.size() == 1 && urls[0].isLocalFile() && urls[0].toEncoded() == text) { QString spaceOnlyText = urls[0].toString(QUrl::EncodeSpaces); if (spaceOnlyText != text) { // Set new mime data. QMimeData *data = new QMimeData(); data->setUrls(urls); data->setText(spaceOnlyText); clipboard->setMimeData(data); clipboard->setProperty(c_ClipboardPropertyMark.toLatin1(), true); qDebug() << "clipboard copy image URL altered" << spaceOnlyText; } } } }); } #endif QMenu *menu = page()->createStandardContextMenu(); menu->setToolTipsVisible(true); const QList actions = menu->actions(); if (!hasSelection() && m_file && m_file->isModifiable()) { QAction *editAct= new QAction(VIconUtils::menuIcon(":/resources/icons/edit_note.svg"), tr("&Edit"), menu); editAct->setToolTip(tr("Edit current note")); connect(editAct, &QAction::triggered, this, &VWebView::handleEditAction); menu->insertAction(actions.isEmpty() ? NULL : actions[0], editAct); // actions does not contain editAction. if (!actions.isEmpty()) { menu->insertSeparator(actions[0]); } } // We need to replace the "Copy Image" action, because the default one use // the fully-encoded URL to fetch the image while Windows seems to not // recognize it. #if defined(Q_OS_WIN) QAction *defaultCopyImageAct = pageAction(QWebEnginePage::CopyImageToClipboard); if (defaultCopyImageAct && actions.contains(defaultCopyImageAct)) { QAction *copyImageAct = new QAction(defaultCopyImageAct->text(), menu); copyImageAct->setToolTip(defaultCopyImageAct->toolTip()); connect(copyImageAct, &QAction::triggered, this, &VWebView::copyImage); menu->insertAction(defaultCopyImageAct, copyImageAct); menu->removeAction(defaultCopyImageAct); } #endif menu->exec(p_event->globalPos()); delete menu; } void VWebView::handleEditAction() { emit editNote(); } void VWebView::copyImage() { Q_ASSERT(m_actionHooked); // triggerPageAction(QWebEnginePage::CopyImageUrlToClipboard) will not really // trigger the corresponding action. It just do the stuff directly. QAction *copyImageUrlAct = pageAction(QWebEnginePage::CopyImageUrlToClipboard); copyImageUrlAct->trigger(); QCoreApplication::processEvents(); QClipboard *clipboard = QApplication::clipboard(); if (clipboard->property(c_ClipboardPropertyMark.toLatin1()).toBool()) { const QMimeData *mimeData = clipboard->mimeData(); QString imgPath; if (mimeData->hasUrls()) { QList urls = mimeData->urls(); if (urls[0].isLocalFile()) { imgPath = urls[0].toLocalFile(); } } if (!imgPath.isEmpty()) { QImage img(imgPath); if (!img.isNull()) { VClipboardUtils::setImageToClipboard(clipboard, img, QClipboard::Clipboard); qDebug() << "clipboard copy image via URL" << imgPath; return; } } } // Fall back. triggerPageAction(QWebEnginePage::CopyImageToClipboard); }