support downloading image from URL

Signed-off-by: Le Tan <tamlokveer@gmail.com>
This commit is contained in:
Le Tan 2016-11-01 21:32:30 +08:00
parent 047c26b598
commit 435d47bb74
7 changed files with 171 additions and 53 deletions

View File

@ -118,3 +118,15 @@ void VInsertImageDialog::setBrowseable(bool browseable)
pathEdit->setVisible(browseable); pathEdit->setVisible(browseable);
browseBtn->setVisible(browseable); browseBtn->setVisible(browseable);
} }
void VInsertImageDialog::imageDownloaded(const QByteArray &data)
{
setImage(QImage::fromData(data));
}
QImage VInsertImageDialog::getImage() const
{
if (!image) {
return QImage();
} else return *image;
}

View File

@ -4,6 +4,7 @@
#include <QDialog> #include <QDialog>
#include <QImage> #include <QImage>
#include <QString> #include <QString>
#include <QByteArray>
class QLabel; class QLabel;
class QLineEdit; class QLineEdit;
@ -21,8 +22,12 @@ public:
QString getPathInput() const; QString getPathInput() const;
void setImage(const QImage &image); void setImage(const QImage &image);
QImage getImage() const;
void setBrowseable(bool browseable); void setBrowseable(bool browseable);
public slots:
void imageDownloaded(const QByteArray &data);
private slots: private slots:
void enableOkButton(); void enableOkButton();
void handleBrowseBtnClicked(); void handleBrowseBtnClicked();

View File

@ -4,7 +4,7 @@
# #
#------------------------------------------------- #-------------------------------------------------
QT += core gui webenginewidgets webchannel QT += core gui webenginewidgets webchannel network
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
@ -39,7 +39,8 @@ SOURCES += main.cpp\
dialog/vfileinfodialog.cpp \ dialog/vfileinfodialog.cpp \
veditoperations.cpp \ veditoperations.cpp \
vmdeditoperations.cpp \ vmdeditoperations.cpp \
dialog/vinsertimagedialog.cpp dialog/vinsertimagedialog.cpp \
vdownloader.cpp
HEADERS += vmainwindow.h \ HEADERS += vmainwindow.h \
vdirectorytree.h \ vdirectorytree.h \
@ -69,7 +70,8 @@ HEADERS += vmainwindow.h \
dialog/vfileinfodialog.h \ dialog/vfileinfodialog.h \
veditoperations.h \ veditoperations.h \
vmdeditoperations.h \ vmdeditoperations.h \
dialog/vinsertimagedialog.h dialog/vinsertimagedialog.h \
vdownloader.h
RESOURCES += \ RESOURCES += \
vnote.qrc vnote.qrc

23
src/vdownloader.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "vdownloader.h"
VDownloader::VDownloader(QObject *parent)
: QObject(parent)
{
connect(&webCtrl, &QNetworkAccessManager::finished,
this, &VDownloader::handleDownloadFinished);
}
void VDownloader::handleDownloadFinished(QNetworkReply *reply)
{
data = reply->readAll();
reply->deleteLater();
emit downloadFinished(data);
}
void VDownloader::download(QUrl url)
{
Q_ASSERT(url.isValid());
QNetworkRequest request(url);
webCtrl.get(request);
qDebug() << "VDownloader get" << url.toString();
}

29
src/vdownloader.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef VDOWNLOADER_H
#define VDOWNLOADER_H
#include <QObject>
#include <QUrl>
#include <QByteArray>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
class VDownloader : public QObject
{
Q_OBJECT
public:
explicit VDownloader(QObject *parent = 0);
void download(QUrl url);
signals:
void downloadFinished(const QByteArray &data);
private slots:
void handleDownloadFinished(QNetworkReply *reply);
private:
QNetworkAccessManager webCtrl;
QByteArray data;
};
#endif // VDOWNLOADER_H

View File

@ -12,6 +12,7 @@
#include "vnotefile.h" #include "vnotefile.h"
#include "utils/vutils.h" #include "utils/vutils.h"
#include "vedit.h" #include "vedit.h"
#include "vdownloader.h"
VMdEditOperations::VMdEditOperations(VEdit *editor, VNoteFile *noteFile) VMdEditOperations::VMdEditOperations(VEdit *editor, VNoteFile *noteFile)
: VEditOperations(editor, noteFile) : VEditOperations(editor, noteFile)
@ -29,8 +30,16 @@ bool VMdEditOperations::insertImageFromMimeData(const QMimeData *source)
dialog.setBrowseable(false); dialog.setBrowseable(false);
dialog.setImage(image); dialog.setImage(image);
if (dialog.exec() == QDialog::Accepted) { if (dialog.exec() == QDialog::Accepted) {
QString title = dialog.getImageTitleInput(); insertImageFromQImage(dialog.getImageTitleInput(),
QString path = QDir::cleanPath(QDir(noteFile->basePath).filePath("images")); QDir::cleanPath(QDir(noteFile->basePath).filePath("images")),
image);
}
return true;
}
void VMdEditOperations::insertImageFromQImage(const QString &title, const QString &path,
const QImage &image)
{
QString fileName = VUtils::generateImageFileName(path, title); QString fileName = VUtils::generateImageFileName(path, title);
qDebug() << "insert image" << path << title << fileName; qDebug() << "insert image" << path << title << fileName;
QString filePath = QDir(path).filePath(fileName); QString filePath = QDir(path).filePath(fileName);
@ -40,44 +49,77 @@ bool VMdEditOperations::insertImageFromMimeData(const QMimeData *source)
QMessageBox msgBox(QMessageBox::Warning, QObject::tr("Warning"), QString("Fail to save image %1").arg(filePath), QMessageBox msgBox(QMessageBox::Warning, QObject::tr("Warning"), QString("Fail to save image %1").arg(filePath),
QMessageBox::Ok, (QWidget *)editor); QMessageBox::Ok, (QWidget *)editor);
msgBox.exec(); msgBox.exec();
return true; return;
} }
QString md = QString("![%1](images/%2)").arg(title).arg(fileName); QString md = QString("![%1](images/%2)").arg(title).arg(fileName);
insertTextAtCurPos(md); insertTextAtCurPos(md);
}
return true;
} }
bool VMdEditOperations::insertImageFromPath(const QString &imagePath) void VMdEditOperations::insertImageFromPath(const QString &title,
const QString &path, const QString &oriImagePath)
{ {
QImage image(imagePath); QString fileName = VUtils::generateImageFileName(path, title, QFileInfo(oriImagePath).suffix());
qDebug() << "insert image" << path << title << fileName << oriImagePath;
QString filePath = QDir(path).filePath(fileName);
Q_ASSERT(!QFile(filePath).exists());
bool ret = QFile::copy(oriImagePath, filePath);
if (!ret) {
qWarning() << "error: fail to copy" << oriImagePath << "to" << filePath;
QMessageBox msgBox(QMessageBox::Warning, QObject::tr("Warning"), QString("Fail to save image %1").arg(filePath),
QMessageBox::Ok, (QWidget *)editor);
msgBox.exec();
return;
}
QString md = QString("![%1](images/%2)").arg(title).arg(fileName);
insertTextAtCurPos(md);
}
bool VMdEditOperations::insertImageFromURL(const QUrl &imageUrl)
{
QString imagePath;
QImage image;
bool isLocal = imageUrl.isLocalFile();
QString title;
// Whether it is a local file or web URL
if (isLocal) {
imagePath = imageUrl.toLocalFile();
image = QImage(imagePath);
if (image.isNull()) { if (image.isNull()) {
qWarning() << "error: image is null"; qWarning() << "error: image is null";
return false; return false;
} }
VInsertImageDialog dialog(QObject::tr("Insert image from file"), QObject::tr("image_title"), title = "Insert image from file";
"", (QWidget *)editor); } else {
dialog.setBrowseable(false); imagePath = imageUrl.toString();
dialog.setImage(image); title = "Insert image from network";
if (dialog.exec() == QDialog::Accepted) {
QString title = dialog.getImageTitleInput();
QString path = QDir::cleanPath(QDir(noteFile->basePath).filePath("images"));
QString fileName = VUtils::generateImageFileName(path, title, QFileInfo(imagePath).suffix());
qDebug() << "insert image" << path << title << fileName;
QString filePath = QDir(path).filePath(fileName);
Q_ASSERT(!QFile(filePath).exists());
bool ret = QFile::copy(imagePath, filePath);
if (!ret) {
qWarning() << "error: fail to copy" << imagePath << "to" << filePath;
QMessageBox msgBox(QMessageBox::Warning, QObject::tr("Warning"), QString("Fail to save image %1").arg(filePath),
QMessageBox::Ok, (QWidget *)editor);
msgBox.exec();
return false;
} }
QString md = QString("![%1](images/%2)").arg(title).arg(fileName);
insertTextAtCurPos(md); VInsertImageDialog dialog(title, QObject::tr("image_title"), imagePath, (QWidget *)editor);
dialog.setBrowseable(false);
if (isLocal) {
dialog.setImage(image);
} else {
// Download it to a QImage
VDownloader *downloader = new VDownloader(&dialog);
QObject::connect(downloader, &VDownloader::downloadFinished,
&dialog, &VInsertImageDialog::imageDownloaded);
downloader->download(imageUrl.toString());
}
if (dialog.exec() == QDialog::Accepted) {
if (isLocal) {
insertImageFromPath(dialog.getImageTitleInput(),
QDir::cleanPath(QDir(noteFile->basePath).filePath("images")),
imagePath);
} else {
insertImageFromQImage(dialog.getImageTitleInput(),
QDir::cleanPath(QDir(noteFile->basePath).filePath("images")),
dialog.getImage());
}
} }
return true; return true;
} }
@ -85,17 +127,17 @@ bool VMdEditOperations::insertImageFromPath(const QString &imagePath)
bool VMdEditOperations::insertURLFromMimeData(const QMimeData *source) bool VMdEditOperations::insertURLFromMimeData(const QMimeData *source)
{ {
foreach (QUrl url, source->urls()) { foreach (QUrl url, source->urls()) {
QString urlStr;
if (url.isLocalFile()) { if (url.isLocalFile()) {
QFileInfo info(url.toLocalFile()); urlStr = url.toLocalFile();
if (QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1())) {
insertImageFromPath(info.filePath());
} else { } else {
insertTextAtCurPos(url.toLocalFile()); urlStr = url.toString();
} }
QFileInfo info(urlStr);
if (QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1())) {
insertImageFromURL(url);
} else { } else {
// TODO: download http image insertTextAtCurPos(urlStr);
// Just insert the URL for non-image
insertTextAtCurPos(url.toString());
} }
} }
return true; return true;

View File

@ -2,6 +2,9 @@
#define VMDEDITOPERATIONS_H #define VMDEDITOPERATIONS_H
#include <QObject> #include <QObject>
#include <QString>
#include <QUrl>
#include <QImage>
#include "veditoperations.h" #include "veditoperations.h"
// Editor operations for Markdown // Editor operations for Markdown
@ -11,7 +14,9 @@ public:
VMdEditOperations(VEdit *editor, VNoteFile *noteFile); VMdEditOperations(VEdit *editor, VNoteFile *noteFile);
bool insertImageFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; bool insertImageFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE;
bool insertURLFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE; bool insertURLFromMimeData(const QMimeData *source) Q_DECL_OVERRIDE;
bool insertImageFromPath(const QString &imagePath); bool insertImageFromURL(const QUrl &imageUrl);
void insertImageFromPath(const QString &title, const QString &path, const QString &oriImagePath);
void insertImageFromQImage(const QString &title, const QString &path, const QImage &image);
}; };
#endif // VMDEDITOPERATIONS_H #endif // VMDEDITOPERATIONS_H