Просмотр исходного кода

Load FB2 from QWebView with images data

Kandrashin Denis 13 лет назад
Родитель
Сommit
1e3cb6aee8
5 измененных файлов с 82 добавлено и 50 удалено
  1. 3 4
      source/fb2main.cpp
  2. 26 36
      source/fb2read.cpp
  3. 13 10
      source/fb2read.h
  4. 30 0
      source/fb2view.cpp
  5. 10 0
      source/fb2view.h

+ 3 - 4
source/fb2main.cpp

@@ -150,9 +150,8 @@ void MainWindow::fileOpen()
 
     if (textEdit) {
         if (isUntitled && !isWindowModified()) {
-            thread = new Fb2ReadThread(this, filename);
-            connect(thread, SIGNAL(sendDocument()), SLOT(sendDocument()));
-            thread->start();
+            Fb2WebView *view = dynamic_cast<Fb2WebView*>(textEdit);
+            view->load(filename);
         } else {
             MainWindow * other = new MainWindow(filename, NULL);
             other->move(x() + 40, y() + 40);
@@ -172,7 +171,7 @@ void MainWindow::fileOpen()
 
 void MainWindow::sendDocument()
 {
-    setCurrentFile(thread->file(), thread->html());
+//    setCurrentFile(thread->file(), thread->html());
     return;
 
     treeView = new QTreeView(this);

+ 26 - 36
source/fb2read.cpp

@@ -20,32 +20,36 @@ Fb2ReadThread::~Fb2ReadThread()
     wait();
 }
 
-QString Fb2ReadThread::file()
+void Fb2ReadThread::stop()
 {
     QMutexLocker locker(&mutex);
     Q_UNUSED(locker);
-    return m_filename;
+    m_abort = true;
 }
 
-QString Fb2ReadThread::html()
+void Fb2ReadThread::run()
 {
-    QMutexLocker locker(&mutex);
-    Q_UNUSED(locker);
-    return m_html;
+    if (parse()) emit html(m_html);
 }
 
-void Fb2ReadThread::stop()
+void Fb2ReadThread::onImage(const QString &name, const QByteArray &data)
 {
-    QMutexLocker locker(&mutex);
-    Q_UNUSED(locker);
-    m_abort = true;
+    emit image(name, data);
 }
 
-void Fb2ReadThread::run()
+bool Fb2ReadThread::parse()
 {
-    if (Fb2Handler::toHTML(m_filename, m_html)) {
-        emit sendDocument();
+    QFile file(m_filename);
+    if (!file.open(QFile::ReadOnly | QFile::Text)) {
+        qCritical() << QObject::tr("Cannot read file %1:\n%2.").arg(m_filename).arg(file.errorString());
+        return false;
     }
+    Fb2Handler handler(*this, m_html);
+    QXmlSimpleReader reader;
+    reader.setContentHandler(&handler);
+    reader.setErrorHandler(&handler);
+    QXmlInputSource source(&file);
+    return reader.parse(source);
 }
 
 //---------------------------------------------------------------------------
@@ -123,8 +127,9 @@ FB2_BEGIN_KEYHASH(RootHandler)
     insert("binary", Binary);
 FB2_END_KEYHASH
 
-Fb2Handler::RootHandler::RootHandler(QXmlStreamWriter &writer, const QString &name)
+Fb2Handler::RootHandler::RootHandler(Fb2ReadThread &thread, QXmlStreamWriter &writer, const QString &name)
     : BaseHandler(name)
+    , m_thread(thread)
     , m_writer(writer)
 {
     m_writer.writeStartElement("html");
@@ -142,7 +147,7 @@ Fb2Handler::BaseHandler * Fb2Handler::RootHandler::NewTag(const QString &name, c
     switch (toKeyword(name)) {
         case Body   : return new BodyHandler(m_writer, name, attributes, "div", name);
         case Descr  : return new DescrHandler(m_writer, name);
-        case Binary : return new BinaryHandler(name, attributes);
+        case Binary : return new BinaryHandler(m_thread, name, attributes);
         default: return NULL;
     }
 }
@@ -287,8 +292,9 @@ Fb2Handler::ImageHandler::ImageHandler(QXmlStreamWriter &writer, const QString &
 //  Fb2Handler::BinaryHandler
 //---------------------------------------------------------------------------
 
-Fb2Handler::BinaryHandler::BinaryHandler(const QString &name, const QXmlAttributes &attributes)
+Fb2Handler::BinaryHandler::BinaryHandler(Fb2ReadThread &thread, const QString &name, const QXmlAttributes &attributes)
     : BaseHandler(name)
+    , m_thread(thread)
     , m_file(Value(attributes, "id"))
 {
 }
@@ -302,17 +308,17 @@ void Fb2Handler::BinaryHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
     QByteArray in; in.append(m_text);
-    QImage img = QImage::fromData(QByteArray::fromBase64(in));
-//    if (!m_file.isEmpty()) m_document.addResource(QTextDocument::ImageResource, QUrl(m_file), img);
+    if (!m_file.isEmpty()) m_thread.onImage(m_file, QByteArray::fromBase64(in));
 }
 
 //---------------------------------------------------------------------------
 //  Fb2Handler
 //---------------------------------------------------------------------------
 
-Fb2Handler::Fb2Handler(QString &string)
+Fb2Handler::Fb2Handler(Fb2ReadThread &thread, QString &string)
     : QXmlDefaultHandler()
     , m_writer(&string)
+    , m_thread(thread)
     , m_handler(NULL)
 {
     m_writer.setAutoFormatting(true);
@@ -334,7 +340,7 @@ bool Fb2Handler::startElement(const QString & namespaceURI, const QString & loca
     qCritical() << name;
 
     if (name == "fictionbook") {
-        m_handler = new RootHandler(m_writer, name);
+        m_handler = new RootHandler(m_thread, m_writer, name);
         return true;
     } else {
         m_error = QObject::tr("The file is not an FB2 file.");
@@ -378,22 +384,6 @@ QString Fb2Handler::errorString() const
     return m_error;
 }
 
-bool Fb2Handler::toHTML(const QString &filename, QString &html)
-{
-    QFile file(filename);
-    if (!file.open(QFile::ReadOnly | QFile::Text)) {
-        qCritical() << QObject::tr("Cannot read file %1:\n%2.").arg(filename).arg(file.errorString());
-        return false;
-    }
-
-    Fb2Handler handler(html);
-    QXmlSimpleReader reader;
-    reader.setContentHandler(&handler);
-    reader.setErrorHandler(&handler);
-    QXmlInputSource source(&file);
-    return reader.parse(source);
-}
-
 #undef FB2_BEGIN_KEYHASH
 
 #undef FB2_END_KEYHASH

+ 13 - 10
source/fb2read.h

@@ -1,6 +1,7 @@
 #ifndef FB2READ_H
 #define FB2READ_H
 
+#include <QByteArray>
 #include <QMutex>
 #include <QThread>
 #include <QXmlDefaultHandler>
@@ -18,12 +19,11 @@ class Fb2ReadThread : public QThread
 public:
     Fb2ReadThread(QObject *parent, const QString &filename);
     ~Fb2ReadThread();
-    void Read(const QString &filename);
-    QString file();
-    QString html();
+    void onImage(const QString &name, const QByteArray &data);
 
 signals:
-    void sendDocument();
+    void image(QString name, QByteArray data);
+    void html(QString html);
 
 public slots:
     void stop();
@@ -31,6 +31,9 @@ public slots:
 protected:
     void run();
 
+private:
+    bool parse();
+
 private:
     const QString m_filename;
     QString m_html;
@@ -48,7 +51,7 @@ static Keyword toKeyword(const QString &name); private:
 class Fb2Handler : public QXmlDefaultHandler
 {
 public:
-    explicit Fb2Handler(QString &string);
+    explicit Fb2Handler(Fb2ReadThread &thread, QString &string);
     virtual ~Fb2Handler();
     bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes);
     bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
@@ -87,11 +90,12 @@ private:
             Binary,
         FB2_END_KEYLIST
     public:
-        explicit RootHandler(QXmlStreamWriter &writer, const QString &name);
+        explicit RootHandler(Fb2ReadThread &thread, QXmlStreamWriter &writer, const QString &name);
         virtual ~RootHandler();
     protected:
         virtual BaseHandler * NewTag(const QString & name, const QXmlAttributes &attributes);
     private:
+        Fb2ReadThread &m_thread;
         QXmlStreamWriter &m_writer;
     };
 
@@ -169,20 +173,19 @@ private:
     class BinaryHandler : public BaseHandler
     {
     public:
-        explicit BinaryHandler(const QString &name, const QXmlAttributes &attributes);
+        explicit BinaryHandler(Fb2ReadThread &thread, const QString &name, const QXmlAttributes &attributes);
     protected:
         virtual void TxtTag(const QString &text);
         virtual void EndTag(const QString &name);
     private:
+        Fb2ReadThread &m_thread;
         QString m_file;
         QString m_text;
     };
 
-public:
-    static bool toHTML(const QString &filename, QString &html);
-
 private:
     QXmlStreamWriter m_writer;
+    Fb2ReadThread & m_thread;
     RootHandler * m_handler;
     QString m_error;
 };

+ 30 - 0
source/fb2view.cpp

@@ -1,4 +1,6 @@
 #include "fb2view.h"
+#include "fb2read.h"
+
 #include <QtDebug>
 #include <QNetworkReply>
 #include <QNetworkRequest>
@@ -20,12 +22,18 @@ QNetworkReply * Fb2NetworkAccessManager::createRequest(Operation op, const QNetw
     return QNetworkAccessManager::createRequest(op, request, outgoingData);
 }
 
+void Fb2NetworkAccessManager::insert(const QString &file, const QByteArray &data)
+{
+    m_images.insert(file, data);
+}
+
 //---------------------------------------------------------------------------
 //  Fb2WebView
 //---------------------------------------------------------------------------
 
 Fb2WebView::Fb2WebView(QWidget *parent)
     : Fb2BaseWebView(parent)
+    , m_thread(0)
 {
     page()->setContentEditable(true);
     QWebSettings *settings = page()->settings();
@@ -37,6 +45,28 @@ Fb2WebView::Fb2WebView(QWidget *parent)
     page()->setNetworkAccessManager(&m_network);
 }
 
+bool Fb2WebView::load(const QString &filename)
+{
+    if (m_thread) return false;
+    m_thread = new Fb2ReadThread(this, filename);
+    connect(m_thread, SIGNAL(image(QString, QByteArray)), SLOT(image(QString, QByteArray)));
+    connect(m_thread, SIGNAL(html(QString)), SLOT(html(QString)));
+    m_thread->start();
+}
+
+void Fb2WebView::image(QString file, QByteArray data)
+{
+    m_network.insert(file, data);
+    qCritical() << file;
+}
+
+void Fb2WebView::html(QString html)
+{
+    setHtml(html, QUrl("fb2://s/"));
+    if (m_thread) m_thread->deleteLater();
+    m_thread = 0;
+}
+
 void Fb2WebView::zoomIn()
 {
     qreal zoom = zoomFactor();

+ 10 - 0
source/fb2view.h

@@ -1,9 +1,11 @@
 #ifndef FB2VIEW_H
 #define FB2VIEW_H
 
+#include <QMap>
 #include <QNetworkAccessManager>
 #include <QResizeEvent>
 #include <QTimer>
+#include <QThread>
 #include <QWebView>
 
 class Fb2NetworkAccessManager : public QNetworkAccessManager
@@ -11,10 +13,14 @@ class Fb2NetworkAccessManager : public QNetworkAccessManager
     Q_OBJECT
 public:
     explicit Fb2NetworkAccessManager(QObject *parent = 0);
+    void insert(const QString &file, const QByteArray &data);
 
 protected:
     virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0);
 
+private:
+    QMap<QString, QByteArray> m_images;
+
 };
 
 class Fb2BaseWebView : public QWebView
@@ -53,16 +59,20 @@ class Fb2WebView : public Fb2BaseWebView
     Q_OBJECT
 public:
     explicit Fb2WebView(QWidget *parent = 0);
+    bool load(const QString &filename);
     
 signals:
     
 public slots:
+    void image(QString file, QByteArray data);
+    void html(QString html);
     void zoomIn();
     void zoomOut();
     void zoomOrig();
 
 private:
     Fb2NetworkAccessManager m_network;
+    QThread *m_thread;
 };
 
 #endif // FB2VIEW_H