Răsfoiți Sursa

Insert image file

Kandrashin Denis 13 ani în urmă
părinte
comite
2f294ef1cb
9 a modificat fișierele cu 92 adăugiri și 71 ștergeri
  1. 4 3
      source/fb2read.cpp
  2. 2 1
      source/fb2read.hpp
  3. 12 32
      source/fb2save.cpp
  4. 1 3
      source/fb2save.hpp
  5. 47 12
      source/fb2temp.cpp
  6. 12 5
      source/fb2temp.hpp
  7. 10 12
      source/fb2view.cpp
  8. 2 3
      source/fb2view.hpp
  9. 2 0
      source/js/export.js

+ 4 - 3
source/fb2read.cpp

@@ -340,6 +340,7 @@ Fb2ReadHandler::ImageHandler::ImageHandler(Fb2ReadHandler &owner, const QString
 Fb2ReadHandler::BinaryHandler::BinaryHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts)
     : BaseHandler(owner, name)
     , m_file(Value(atts, "id"))
+    , m_type(Value(atts, "content-type"))
 {
 }
 
@@ -352,7 +353,7 @@ void Fb2ReadHandler::BinaryHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
     QByteArray in; in.append(m_text);
-    if (!m_file.isEmpty()) m_owner.addFile(m_file, QByteArray::fromBase64(in));
+    if (!m_file.isEmpty()) m_owner.addFile(m_file, m_type, QByteArray::fromBase64(in));
 }
 
 //---------------------------------------------------------------------------
@@ -383,7 +384,7 @@ QString Fb2ReadHandler::getFile(const QString &name)
     return path;
 }
 
-void Fb2ReadHandler::addFile(const QString &name, const QByteArray &data)
+void Fb2ReadHandler::addFile(const QString &name, const QString &type, const QByteArray &data)
 {
-    QMetaObject::invokeMethod(m_thread.parent(), "data", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QByteArray, data));
+    QMetaObject::invokeMethod(m_thread.parent(), "data", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QString, type), Q_ARG(QByteArray, data));
 }

+ 2 - 1
source/fb2read.hpp

@@ -162,6 +162,7 @@ private:
         virtual void EndTag(const QString &name);
     private:
         QString m_file;
+        QString m_type;
         QString m_text;
     };
 
@@ -169,7 +170,7 @@ protected:
     virtual NodeHandler * CreateRoot(const QString &name, const QXmlAttributes &atts);
 
 private:
-    void addFile(const QString &name, const QByteArray &data);
+    void addFile(const QString &name, const QString &type, const QByteArray &data);
     QString getFile(const QString &name);
 
 private:

+ 12 - 32
source/fb2save.cpp

@@ -117,6 +117,11 @@ void Fb2HtmlHandler::onTxt(const QString &text)
     characters(text);
 }
 
+void Fb2HtmlHandler::onCom(const QString &text)
+{
+    Q_UNUSED(text);
+}
+
 void Fb2HtmlHandler::onEnd(const QString &name)
 {
     endElement("", local(name), name);
@@ -184,21 +189,6 @@ QByteArray Fb2SaveWriter::downloadFile(const QUrl &url)
     return reply->readAll();
 }
 
-QString Fb2SaveWriter::newFileName(const QString &path)
-{
-    QFileInfo info(path);
-    QString name = info.fileName();
-    if (!m_view.files().exists(name) && !m_files.exists(name)) return name;
-    QString base = info.baseName();
-    QString suff = info.suffix();
-    for (int i = 1; ; i++) {
-        QString name = QString("%1(%2).%3").arg(base).arg(i).arg(suff);
-        if (m_view.files().exists(name)) continue;
-        if (m_files.exists(name)) continue;
-        return name;
-    }
-}
-
 QString Fb2SaveWriter::getFileName(const QString &path)
 {
     QUrl url = path;
@@ -212,36 +202,26 @@ QString Fb2SaveWriter::getFileName(const QString &path)
     } else {
         QByteArray data = downloadFile(url);
         if (data.size() == 0) return QString();
-        QString hash = Fb2TemporaryFile::md5(data);
-        QString name = m_view.files().name(hash);
-        if (name.isEmpty()) m_files.name(hash);
-        if (name.isEmpty()) {
-            name = newFileName(url.path());
-            m_files.set(name, data, hash);
-            m_names.append(name);
-        }
+        QString name = m_view.files().add(url.path(), data);
+        m_names.append(name);
         return name;
     }
 }
 
-QByteArray Fb2SaveWriter::getFileData(const QString &name)
-{
-    QByteArray data = m_view.files().data(name);
-    if (data.size() == 0) data = m_files.data(name);
-    return data;
-}
-
 void Fb2SaveWriter::writeFiles()
 {
     QStringListIterator it(m_names);
     while (it.hasNext()) {
         QString name = it.next();
         if (name.isEmpty()) continue;
-        QString data = getFileData(name).toBase64();
-        if (data.isEmpty()) continue;
+        Fb2TemporaryFile * file = m_view.files().get(name);
+        if (!file) continue;
+        QString type = file->type();
+        QString data = file->data().toBase64();
         writeStartElement("binary", 2);
         if (m_folds) m_folds->append(m_line);
         writeAttribute("id", name);
+        if (!type.isEmpty()) writeAttribute("content-type", type);
         writeLineEnd();
         int pos = 0;
         while (true) {

+ 1 - 3
source/fb2save.hpp

@@ -54,6 +54,7 @@ public slots:
     void onNew(const QString &name);
     void onEnd(const QString &name);
     void onTxt(const QString &text);
+    void onCom(const QString &text);
 
 private:
     static QString local(const QString &name);
@@ -76,12 +77,9 @@ public:
     void writeFiles();
 private:
     QByteArray downloadFile(const QUrl &url);
-    QByteArray getFileData(const QString &name);
-    QString newFileName(const QString &path);
 private:
     QList<int> *m_folds;
     Fb2WebView &m_view;
-    Fb2TemporaryList m_files;
     QStringList m_names;
     int m_line;
 };

+ 47 - 12
source/fb2temp.cpp

@@ -1,6 +1,8 @@
 #include "fb2temp.hpp"
 
 #include <QCryptographicHash>
+#include <QFileInfo>
+#include <QImageReader>
 #include <QUrl>
 #include <QtDebug>
 
@@ -10,10 +12,9 @@
 //  Fb2TemporaryFile
 //---------------------------------------------------------------------------
 
-Fb2TemporaryFile::Fb2TemporaryFile(const QString &name, const QString &hash)
+Fb2TemporaryFile::Fb2TemporaryFile(const QString &name)
     : QTemporaryFile()
     , m_name(name)
-    , m_hash(hash)
 {
 }
 
@@ -53,16 +54,47 @@ Fb2TemporaryList::~Fb2TemporaryList()
     while (it.hasNext()) delete it.next();
 }
 
-Fb2TemporaryFile & Fb2TemporaryList::get(const QString &name, const QString &hash)
+QString Fb2TemporaryList::add(const QString &path, const QByteArray &data)
+{
+    QString hash = Fb2TemporaryFile::md5(data);
+    QString name = this->name(hash);
+    if (name.isEmpty()) {
+        name = newName(path);
+        Fb2TemporaryFile * temp = new Fb2TemporaryFile(name);
+        temp->setHash(hash);
+        temp->write(data);
+        temp->open();
+        QString type = QImageReader::imageFormat(temp);
+        if (!type.isEmpty()) type.prepend("image/");
+        temp->setType(type);
+        temp->close();
+        append(temp);
+    }
+    return name;
+}
+
+QString Fb2TemporaryList::newName(const QString &path)
+{
+    QFileInfo info(path);
+    QString name = info.fileName();
+    if (!exists(name)) return name;
+    QString base = info.baseName();
+    QString suff = info.suffix();
+    for (int i = 1; ; i++) {
+        QString name = QString("%1(%2).%3").arg(base).arg(i).arg(suff);
+        if (exists(name)) continue;
+        return name;
+    }
+}
+
+Fb2TemporaryFile * Fb2TemporaryList::get(const QString &name) const
 {
     Fb2TemporaryIterator it(*this);
     while (it.hasNext()) {
-        Fb2TemporaryFile *file = it.next();
-        if (file->name() == name) return *file;
+        Fb2TemporaryFile * file = it.next();
+        if (file->name() == name) return file;
     }
-    Fb2TemporaryFile * file = new Fb2TemporaryFile(name, hash);
-    append(file);
-    return *file;
+    return NULL;
 }
 
 QByteArray Fb2TemporaryList::data(const QString &name) const
@@ -75,11 +107,14 @@ QByteArray Fb2TemporaryList::data(const QString &name) const
     return QByteArray();
 }
 
-QString Fb2TemporaryList::set(const QString &name, const QByteArray &data, const QString &hash)
+const QString & Fb2TemporaryList::set(const QString &name, const QString &type, const QByteArray &data, const QString &hash)
 {
-    Fb2TemporaryFile & file = get(name, hash);
-    file.write(data);
-    return file.hash();
+    Fb2TemporaryFile * file = get(name);
+    if (!file) append(file = new Fb2TemporaryFile(name));
+    file->setType(type);
+    file->setHash(hash);
+    file->write(data);
+    return file->hash();
 }
 
 QString Fb2TemporaryList::name(const QString &hash) const

+ 12 - 5
source/fb2temp.hpp

@@ -14,14 +14,19 @@ class Fb2TemporaryFile : public QTemporaryFile
 {
     Q_OBJECT
 public:
-    explicit Fb2TemporaryFile(const QString &name, const QString &hash = QString());
+    static QString md5(const QByteArray &data);
+public:
+    explicit Fb2TemporaryFile(const QString &name);
     inline qint64 write(const QByteArray &data);
+    void setHash(const QString &hash) { m_hash = hash; }
+    void setType(const QString &type) { m_type = type; }
     const QString & hash() const { return m_hash; }
     const QString & name() const { return m_name; }
-    static QString md5(const QByteArray &data);
+    const QString & type() const { return m_type; }
     QByteArray data();
 private:
     const QString m_name;
+    QString m_type;
     QString m_hash;
 };
 
@@ -31,12 +36,14 @@ public:
     explicit Fb2TemporaryList();
     virtual ~Fb2TemporaryList();
 
+    QString add(const QString &path, const QByteArray &data);
     bool exists(const QString &name) const;
-    Fb2TemporaryFile & get(const QString &name, const QString &hash = QString());
-    QString set(const QString &name, const QByteArray &data, const QString &hash = QString());
-
+    Fb2TemporaryFile * get(const QString &name) const;
+    const QString & set(const QString &name, const QString &type, const QByteArray &data, const QString &hash = QString());
     QString name(const QString &hash) const;
     QByteArray data(const QString &name) const;
+private:
+    QString newName(const QString &path);
 };
 
 typedef QListIterator<Fb2TemporaryFile*> Fb2TemporaryIterator;

+ 10 - 12
source/fb2view.cpp

@@ -198,14 +198,9 @@ bool Fb2WebView::save(QString *string)
     return ok;
 }
 
-QString Fb2WebView::temp(QString name)
+void Fb2WebView::data(QString name, QString type, QByteArray data)
 {
-    return m_files.get(name).fileName();
-}
-
-void Fb2WebView::data(QString name, QByteArray data)
-{
-    m_files.set(name, data);
+    m_files.set(name, type, data);
 }
 
 void Fb2WebView::html(QString name, QString html)
@@ -286,12 +281,15 @@ void Fb2WebView::insertImage()
     filters += tr("Graphics Interchange Format (*.gif);;");
     filters += tr("All Files (*)");
 
-    QString fn = QFileDialog::getOpenFileName(this, tr("Open image..."), QString(), filters);
-    if (fn.isEmpty()) return;
-    if (!QFile::exists(fn)) return;
+    QString path = QFileDialog::getOpenFileName(this, tr("Insert image..."), QString(), filters);
+    if (path.isEmpty()) return;
+
+    QFile file(path);
+    if (!file.open(QIODevice::ReadOnly)) return;
 
-    QUrl url = QUrl::fromLocalFile(fn);
-    execCommand("insertImage", url.toString());
+    QByteArray data = file.readAll();
+    QString name = m_files.add(path, data);
+    execCommand("insertImage", name.prepend("fb2:"));
 }
 
 void Fb2WebView::insertNote()

+ 2 - 3
source/fb2view.hpp

@@ -64,7 +64,7 @@ public:
     explicit Fb2WebView(QWidget *parent = 0);
     virtual ~Fb2WebView();
 
-    const Fb2TemporaryList & files() const { return m_files; }
+    Fb2TemporaryList & files() { return m_files; }
     void load(const QString &filename, const QString &xml = QString());
     bool save(QIODevice *device, const QString &codec = QString());
     bool save(QByteArray *array, QList<int> *folds = 0);
@@ -88,8 +88,7 @@ protected:
 signals:
     
 public slots:
-    QString temp(QString name);
-    void data(QString name, QByteArray data);
+    void data(QString name, QString type, QByteArray data);
     void html(QString name, QString html);
     void linkHovered(const QString &link, const QString &title, const QString &textContent);
     void showInspector();

+ 2 - 0
source/js/export.js

@@ -1,6 +1,8 @@
 (f = function(node) {
     if (node.nodeName === "#text") {
         handler.onTxt(node.data);
+    } else if (node.nodeName === "#comment") {
+        handler.onCom(node.data);
     } else {
         var atts = node.attributes;
         var count = atts.length;