mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
MdEditor: insert link or content when dropping file in editor
This commit is contained in:
parent
a055d6e935
commit
4d223d0397
@ -119,7 +119,11 @@ void VInsertLinkDialog::fetchLinkFromClipboard()
|
||||
QUrl url = QUrl::fromUserInput(text);
|
||||
if (url.isValid()) {
|
||||
if (m_linkUrlEdit->text().isEmpty()) {
|
||||
m_linkUrlEdit->setText(text);
|
||||
if (url.isLocalFile()) {
|
||||
m_linkUrlEdit->setText(url.toString(QUrl::EncodeSpaces));
|
||||
} else {
|
||||
m_linkUrlEdit->setText(text);
|
||||
}
|
||||
}
|
||||
} else if (m_linkTextEdit->text().isEmpty()) {
|
||||
m_linkTextEdit->setText(text);
|
||||
|
@ -49,8 +49,10 @@ const QString VUtils::c_imageLinkRegExp = QString("\\!\\[([^\\]]*)\\]\\(\\s*([^\
|
||||
|
||||
const QString VUtils::c_imageTitleRegExp = QString("[^\\[\\]]*");
|
||||
|
||||
const QString VUtils::c_linkRegExp = QString("\\[([^\\]]*)\\]\\(\\s*([^\\)\"'\\s]+)\\s*"
|
||||
"((\"[^\"\\)\\n]*\")|('[^'\\)\\n]*'))?\\s*"
|
||||
const QString VUtils::c_linkRegExp = QString("\\[([^\\]]*)\\]"
|
||||
"\\(\\s*(\\S+)"
|
||||
"(?:\\s+((\"[^\"\\n]*\")"
|
||||
"|('[^'\\n]*')))?\\s*"
|
||||
"\\)");
|
||||
|
||||
const QString VUtils::c_fileNameRegExp = QString("(?:[^\\\\/:\\*\\?\"<>\\|\\s]| )*");
|
||||
|
@ -30,7 +30,7 @@ VEditOperations::VEditOperations(VEditor *p_editor, VFile *p_file)
|
||||
}
|
||||
}
|
||||
|
||||
void VEditOperations::insertTextAtCurPos(const QString &p_text)
|
||||
void VEditOperations::insertText(const QString &p_text)
|
||||
{
|
||||
m_editor->insertPlainTextW(p_text);
|
||||
}
|
||||
|
@ -30,6 +30,8 @@ public:
|
||||
virtual bool insertLink(const QString &p_linkText,
|
||||
const QString &p_linkUrl) = 0;
|
||||
|
||||
virtual void insertText(const QString &p_text);
|
||||
|
||||
// Return true if @p_event has been handled and no need to be further
|
||||
// processed.
|
||||
virtual bool handleKeyPressEvent(QKeyEvent *p_event) = 0;
|
||||
@ -68,8 +70,6 @@ private:
|
||||
void updateCursorLineBg();
|
||||
|
||||
protected:
|
||||
void insertTextAtCurPos(const QString &p_text);
|
||||
|
||||
VEditor *m_editor;
|
||||
QPointer<VFile> m_file;
|
||||
VEditConfig *m_editConfig;
|
||||
|
@ -92,7 +92,7 @@ void VMdEditOperations::insertImageFromQImage(const QString &title,
|
||||
|
||||
QString url = QString("%1/%2").arg(folderInLink).arg(fileName);
|
||||
QString md = QString("").arg(title).arg(url);
|
||||
insertTextAtCurPos(md);
|
||||
insertText(md);
|
||||
|
||||
qDebug() << "insert image" << title << filePath;
|
||||
|
||||
@ -133,7 +133,7 @@ void VMdEditOperations::insertImageFromPath(const QString &title, const QString
|
||||
|
||||
QString url = QString("%1/%2").arg(folderInLink).arg(fileName);
|
||||
QString md = QString("").arg(title).arg(url);
|
||||
insertTextAtCurPos(md);
|
||||
insertText(md);
|
||||
|
||||
qDebug() << "insert image" << title << filePath;
|
||||
|
||||
@ -540,7 +540,7 @@ bool VMdEditOperations::handleKeyTab(QKeyEvent *p_event)
|
||||
m_autoIndentPos = m_editor->textCursorW().position();
|
||||
} else {
|
||||
// Just insert "tab".
|
||||
insertTextAtCurPos(text);
|
||||
insertText(text);
|
||||
m_autoIndentPos = -1;
|
||||
}
|
||||
}
|
||||
@ -1128,9 +1128,7 @@ bool VMdEditOperations::insertLink(const QString &p_linkText,
|
||||
const QString &p_linkUrl)
|
||||
{
|
||||
QString link = QString("[%1](%2)").arg(p_linkText).arg(p_linkUrl);
|
||||
QTextCursor cursor = m_editor->textCursorW();
|
||||
cursor.insertText(link);
|
||||
m_editor->setTextCursorW(cursor);
|
||||
insertText(link);
|
||||
|
||||
setVimMode(VimMode::Insert);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <QDebug>
|
||||
#include <QScopedPointer>
|
||||
#include <QClipboard>
|
||||
#include <QMimeDatabase>
|
||||
|
||||
#include "vdocument.h"
|
||||
#include "utils/veditutils.h"
|
||||
@ -850,125 +851,20 @@ bool VMdEditor::canInsertFromMimeData(const QMimeData *p_source) const
|
||||
|
||||
void VMdEditor::insertFromMimeData(const QMimeData *p_source)
|
||||
{
|
||||
if (p_source->hasHtml()) {
|
||||
// Handle <img>.
|
||||
QRegExp reg("<img ([^>]*)src=\"([^\"]+)\"([^>]*)>");
|
||||
QString html(p_source->html());
|
||||
if (reg.indexIn(html) != -1 && VUtils::onlyHasImgInHtml(html)) {
|
||||
if (p_source->hasImage()) {
|
||||
// Both image data and URL are embedded.
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert From URL"), 0);
|
||||
dialog.addSelection(tr("Insert From Image Data"), 1);
|
||||
dialog.addSelection(tr("Insert As Image Link"), 2);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 1) {
|
||||
// Insert from image data.
|
||||
m_editOps->insertImageFromMimeData(p_source);
|
||||
return;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", reg.cap(2));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_editOps->insertImageFromURL(QUrl(reg.cap(2)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert As Image"), 0);
|
||||
dialog.addSelection(tr("Insert As Text"), 1);
|
||||
dialog.addSelection(tr("Insert As Image Link"), 2);
|
||||
|
||||
if (p_source->hasImage()) {
|
||||
// Image data in the clipboard
|
||||
if (p_source->hasText()) {
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 1) {
|
||||
// Insert as text.
|
||||
Q_ASSERT(p_source->hasText() && p_source->hasImage());
|
||||
VTextEdit::insertFromMimeData(p_source);
|
||||
return;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", p_source->text());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_editOps->insertImageFromMimeData(p_source);
|
||||
if (processHtmlFromMimeData(p_source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_source->hasUrls()) {
|
||||
QList<QUrl> urls = p_source->urls();
|
||||
if (urls.size() == 1 && VUtils::isImageURL(urls[0])) {
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
// FIXME: After calling dialog.exec(), p_source->hasUrl() returns false.
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 0) {
|
||||
// Insert as image.
|
||||
m_editOps->insertImageFromURL(urls[0]);
|
||||
return;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", urls[0].toString(QUrl::FullyEncoded));
|
||||
return;
|
||||
}
|
||||
|
||||
QMimeData newSource;
|
||||
newSource.setUrls(urls);
|
||||
VTextEdit::insertFromMimeData(&newSource);
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (processImageFromMimeData(p_source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_source->hasText()) {
|
||||
QString text = p_source->text();
|
||||
if (VUtils::isImageURLText(text)) {
|
||||
// The text is a URL to an image.
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 0) {
|
||||
// Insert as image.
|
||||
QUrl url;
|
||||
if (QFileInfo::exists(text)) {
|
||||
url = QUrl::fromLocalFile(text);
|
||||
} else {
|
||||
url = QUrl(text);
|
||||
}
|
||||
if (processUrlFromMimeData(p_source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.isValid()) {
|
||||
m_editOps->insertImageFromURL(url);
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", text);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(p_source->hasText());
|
||||
if (processTextFromMimeData(p_source)) {
|
||||
return;
|
||||
}
|
||||
|
||||
VTextEdit::insertFromMimeData(p_source);
|
||||
@ -1266,9 +1162,7 @@ void VMdEditor::htmlToTextFinished(int p_id, int p_timeStamp, const QString &p_t
|
||||
{
|
||||
Q_UNUSED(p_id);
|
||||
if (m_copyTimeStamp == p_timeStamp && !p_text.isEmpty()) {
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.insertText(p_text);
|
||||
setTextCursor(cursor);
|
||||
m_editOps->insertText(p_text);
|
||||
emit m_object->statusMessage(tr("Parsed Markdown text inserted"));
|
||||
}
|
||||
}
|
||||
@ -1849,3 +1743,230 @@ void VMdEditor::parseAndPaste()
|
||||
emit requestHtmlToText(html, 0, m_copyTimeStamp);
|
||||
}
|
||||
}
|
||||
|
||||
bool VMdEditor::processHtmlFromMimeData(const QMimeData *p_source)
|
||||
{
|
||||
if (!p_source->hasHtml()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle <img>.
|
||||
QRegExp reg("<img ([^>]*)src=\"([^\"]+)\"([^>]*)>");
|
||||
QString html(p_source->html());
|
||||
if (reg.indexIn(html) != -1 && VUtils::onlyHasImgInHtml(html)) {
|
||||
if (p_source->hasImage()) {
|
||||
// Both image data and URL are embedded.
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert From URL"), 0);
|
||||
dialog.addSelection(tr("Insert From Image Data"), 1);
|
||||
dialog.addSelection(tr("Insert As Image Link"), 2);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 1) {
|
||||
// Insert from image data.
|
||||
m_editOps->insertImageFromMimeData(p_source);
|
||||
return true;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", reg.cap(2));
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_editOps->insertImageFromURL(QUrl(reg.cap(2)));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VMdEditor::processImageFromMimeData(const QMimeData *p_source)
|
||||
{
|
||||
if (!p_source->hasImage()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Image data in the clipboard
|
||||
if (p_source->hasText()) {
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert As Image"), 0);
|
||||
dialog.addSelection(tr("Insert As Text"), 1);
|
||||
dialog.addSelection(tr("Insert As Image Link"), 2);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 1) {
|
||||
// Insert as text.
|
||||
Q_ASSERT(p_source->hasText() && p_source->hasImage());
|
||||
VTextEdit::insertFromMimeData(p_source);
|
||||
return true;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", p_source->text());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_editOps->insertImageFromMimeData(p_source);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VMdEditor::processUrlFromMimeData(const QMimeData *p_source)
|
||||
{
|
||||
if (!p_source->hasUrls()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QUrl> urls = p_source->urls();
|
||||
if (urls.size() == 1) {
|
||||
if (VUtils::isImageURL(urls[0])) {
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert As Image"), 0);
|
||||
dialog.addSelection(tr("Insert As Text"), 1);
|
||||
dialog.addSelection(tr("Insert As Image Link"), 2);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
// FIXME: After calling dialog.exec(), p_source->hasUrl() returns false.
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 0) {
|
||||
// Insert as image.
|
||||
m_editOps->insertImageFromURL(urls[0]);
|
||||
return true;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", urls[0].toString(QUrl::FullyEncoded));
|
||||
return true;
|
||||
}
|
||||
|
||||
QMimeData newSource;
|
||||
newSource.setUrls(urls);
|
||||
VTextEdit::insertFromMimeData(&newSource);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
QString localTextFilePath;
|
||||
if (urls[0].isLocalFile()) {
|
||||
localTextFilePath = urls[0].toLocalFile();
|
||||
if (!QFileInfo::exists(localTextFilePath)) {
|
||||
localTextFilePath.clear();
|
||||
} else {
|
||||
QMimeDatabase mimeDatabase;
|
||||
const QMimeType mimeType = mimeDatabase.mimeTypeForFile(localTextFilePath);
|
||||
if (mimeType.isValid() && !mimeType.inherits(QStringLiteral("text/plain"))) {
|
||||
localTextFilePath.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert As Link"), 0);
|
||||
dialog.addSelection(tr("Insert As Text"), 1);
|
||||
if (!localTextFilePath.isEmpty()) {
|
||||
dialog.addSelection(tr("Insert File Content"), 2);
|
||||
}
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
switch (dialog.getSelection()) {
|
||||
case 0:
|
||||
{
|
||||
QString ut = urls[0].isLocalFile() ? urls[0].toString(QUrl::EncodeSpaces)
|
||||
: urls[0].toString();
|
||||
VInsertLinkDialog ld(QObject::tr("Insert Link"),
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
ut,
|
||||
false,
|
||||
this);
|
||||
if (ld.exec() == QDialog::Accepted) {
|
||||
QString linkText = ld.getLinkText();
|
||||
QString linkUrl = ld.getLinkUrl();
|
||||
Q_ASSERT(!linkText.isEmpty() && !linkUrl.isEmpty());
|
||||
m_editOps->insertLink(linkText, linkUrl);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
if (p_source->hasText()) {
|
||||
m_editOps->insertText(p_source->text());
|
||||
} else {
|
||||
m_editOps->insertText(urls[0].toString());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
{
|
||||
Q_ASSERT(!localTextFilePath.isEmpty());
|
||||
m_editOps->insertText(VUtils::readFileFromDisk(localTextFilePath));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VMdEditor::processTextFromMimeData(const QMimeData *p_source)
|
||||
{
|
||||
if (!p_source->hasText()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QString text = p_source->text();
|
||||
if (VUtils::isImageURLText(text)) {
|
||||
// The text is a URL to an image.
|
||||
VSelectDialog dialog(tr("Insert From Clipboard"), this);
|
||||
dialog.addSelection(tr("Insert As Image"), 0);
|
||||
dialog.addSelection(tr("Insert As Text"), 1);
|
||||
dialog.addSelection(tr("Insert As Image Link"), 2);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
int selection = dialog.getSelection();
|
||||
if (selection == 0) {
|
||||
// Insert as image.
|
||||
QUrl url;
|
||||
if (QFileInfo::exists(text)) {
|
||||
url = QUrl::fromLocalFile(text);
|
||||
} else {
|
||||
url = QUrl(text);
|
||||
}
|
||||
|
||||
if (url.isValid()) {
|
||||
m_editOps->insertImageFromURL(url);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (selection == 2) {
|
||||
// Insert as link.
|
||||
insertImageLink("", text);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(p_source->hasText());
|
||||
return false;
|
||||
}
|
||||
|
@ -305,6 +305,14 @@ private:
|
||||
const QString &p_text,
|
||||
const QString &p_format);
|
||||
|
||||
bool processHtmlFromMimeData(const QMimeData *p_source);
|
||||
|
||||
bool processImageFromMimeData(const QMimeData *p_source);
|
||||
|
||||
bool processUrlFromMimeData(const QMimeData *p_source);
|
||||
|
||||
bool processTextFromMimeData(const QMimeData *p_source);
|
||||
|
||||
PegMarkdownHighlighter *m_pegHighlighter;
|
||||
|
||||
VCodeBlockHighlightHelper *m_cbHighlighter;
|
||||
|
Loading…
x
Reference in New Issue
Block a user