Kandrashin Denis 12 роки тому
батько
коміт
1ec342c6cc
8 змінених файлів з 168 додано та 44 видалено
  1. 46 16
      source/fb2main.cpp
  2. 1 1
      source/fb2main.hpp
  3. 43 4
      source/fb2read.cpp
  4. 28 8
      source/fb2read.hpp
  5. 2 2
      source/fb2temp.cpp
  6. 2 2
      source/fb2temp.hpp
  7. 41 10
      source/fb2text.cpp
  8. 5 1
      source/fb2text.hpp

+ 46 - 16
source/fb2main.cpp

@@ -69,8 +69,15 @@ FbMainWindow::FbMainWindow(const QString &filename, ViewMode mode)
 
     setCurrentFile(filename);
     if (mode == FB2) {
-        viewText();
-        textFrame->view()->load(filename.isEmpty() ? ":blank.fb2" : filename);
+        QString filepath = filename.isEmpty() ? ":blank.fb2" : filename;
+        FbTextPage *page = new FbTextPage(this);
+        if (page->load(filepath, QString())) {
+            viewText(page);
+        } else {
+            delete page;
+            viewCode();
+            if (!filename.isEmpty()) loadXML(filepath);
+        }
     } else {
         viewCode();
         if (!filename.isEmpty()) loadXML(filename);
@@ -165,7 +172,14 @@ void FbMainWindow::fileOpen()
     if (textFrame) {
         if (isUntitled && !isWindowModified()) {
             setCurrentFile(filename);
-            textFrame->view()->load(filename);
+            FbTextPage *page = new FbTextPage(this);
+            if (page->load(filename, QString())) {
+                viewText(page);
+            } else {
+                delete page;
+                viewCode();
+                if (!filename.isEmpty()) loadXML(filename);
+            }
         } else {
             FbMainWindow * other = new FbMainWindow(filename, FB2);
             other->move(x() + 40, y() + 40);
@@ -759,18 +773,20 @@ void FbMainWindow::createTextToolbar()
     tool->addAction(actionSection);
 }
 
-void FbMainWindow::viewText()
+void FbMainWindow::viewText(FbTextPage *page)
 {
     if (textFrame && centralWidget() == textFrame) return;
 
     if (textFrame) textFrame->hideInspector();
 
-    bool load = false;
-    QString xml;
     if (codeEdit) {
-        xml = codeEdit->text();
+        QString xml = codeEdit->text();
+        page = new FbTextPage(this);
+        if (!page->load(QString(), xml)) {
+            delete page;
+            return;
+        }
         isSwitched = true;
-        load = true;
     }
 
     FB2DELETE(codeEdit);
@@ -781,21 +797,24 @@ void FbMainWindow::viewText()
         textFrame = new FbTextFrame(this, actionInspect);
     }
     setCentralWidget(textFrame);
-    viewTree();
 
     FbTextEdit *textEdit = textFrame->view();
 
+    if (page) {
+        page->setParent(textEdit);
+        textEdit->setPage(page);
+    }
+
     connect(textEdit, SIGNAL(loadFinished(bool)), SLOT(createTextToolbar()));
     connect(textEdit->pageAction(QWebPage::Undo), SIGNAL(changed()), SLOT(undoChanged()));
     connect(textEdit->pageAction(QWebPage::Redo), SIGNAL(changed()), SLOT(redoChanged()));
 
-    if (load) textFrame->view()->load(curFile, xml);
-
     actionContents->setEnabled(true);
     actionPictures->setEnabled(true);
     actionInspect->setEnabled(true);
 
-    textFrame->view()->setFocus();
+    textEdit->setFocus();
+    viewTree();
 }
 
 void FbMainWindow::viewHead()
@@ -804,8 +823,16 @@ void FbMainWindow::viewHead()
 
     if (textFrame) textFrame->hideInspector();
 
-    QString xml;
-    if (codeEdit) xml = codeEdit->text();
+    FbTextPage *page = 0;
+    if (codeEdit) {
+        QString xml = codeEdit->text();
+        page = new FbTextPage(this);
+        if (!page->load(QString(), xml)) {
+            delete page;
+            return;
+        }
+        isSwitched = true;
+    }
 
     FB2DELETE(dockTree);
     FB2DELETE(dockImgs);
@@ -814,6 +841,11 @@ void FbMainWindow::viewHead()
 
     if (!textFrame) {
         textFrame = new FbTextFrame(this, actionInspect);
+        FbTextEdit *textEdit = textFrame->view();
+        if (page) {
+            page->setParent(textEdit);
+            textEdit->setPage(page);
+        }
     }
 
     if (!headTree) {
@@ -829,8 +861,6 @@ void FbMainWindow::viewHead()
 
     headTree->setFocus();
 
-    if (!xml.isEmpty()) textFrame->view()->load(curFile, xml);
-
     if (textFrame) {
         actionUndo->disconnect();
         actionRedo->disconnect();

+ 1 - 1
source/fb2main.hpp

@@ -79,7 +79,7 @@ private slots:
     void logShowed();
     void viewCode();
     void viewHtml();
-    void viewText();
+    void viewText(FbTextPage *page = 0);
     void viewHead();
     void viewTree();
     void viewImgs();

+ 43 - 4
source/fb2read.cpp

@@ -8,6 +8,24 @@
 //  FbReadThread
 //---------------------------------------------------------------------------
 
+FbReadThread::FbReadThread(const QString &html, QObject *parent)
+    : QThread(parent)
+    , m_html(html)
+{
+    connect(this, SIGNAL(html(QString,QUrl)), parent, SLOT(html(QString,QUrl)));
+}
+
+void FbReadThread::run()
+{
+
+    sleep(1);
+    static int number = 0;
+    QUrl url(QString("fb2:/%1/").arg(number++));
+    emit html(m_html, url);
+    deleteLater();
+}
+
+/*
 FbReadThread::FbReadThread(QObject *parent, const QString &filename, const QString &xml)
     : QThread(parent)
     , m_temp(0)
@@ -66,6 +84,7 @@ bool FbReadThread::parse()
 {
     QXmlStreamWriter writer(&m_html);
     FbReadHandler handler(*this, writer);
+    connect(&handler, SIGNAL(binary(QString,QByteArray)), this, SLOT(data(QString,QByteArray)));
     QXmlSimpleReader reader;
     reader.setContentHandler(&handler);
     reader.setLexicalHandler(&handler);
@@ -86,6 +105,8 @@ bool FbReadThread::parse()
 
 #endif
 
+*/
+
 //---------------------------------------------------------------------------
 //  FbReadHandler::RootHandler
 //---------------------------------------------------------------------------
@@ -299,11 +320,29 @@ void FbReadHandler::BinaryHandler::EndTag(const QString &name)
 //  FbReadHandler
 //---------------------------------------------------------------------------
 
-FbReadHandler::FbReadHandler(FbReadThread &thread, QXmlStreamWriter &writer)
+bool FbReadHandler::load(QObject *page, QXmlInputSource &source, QString &html)
+{
+    QXmlStreamWriter writer(&html);
+    FbReadHandler handler(writer);
+
+    connect(&handler, SIGNAL(binary(QString,QByteArray)), page, SLOT(binary(QString,QByteArray)));
+
+#ifdef FB2_USE_LIBXML2
+    XML2::XmlReader reader;
+#else
+    QXmlSimpleReader reader;
+#endif
+
+    reader.setContentHandler(&handler);
+    reader.setLexicalHandler(&handler);
+    reader.setErrorHandler(&handler);
+
+    return reader.parse(source);
+}
+
+FbReadHandler::FbReadHandler(QXmlStreamWriter &writer)
     : FbXmlHandler()
-    , m_thread(thread)
     , m_writer(writer)
-    , m_temp(thread.temp())
 {
     m_writer.setAutoFormatting(true);
     m_writer.setAutoFormattingIndent(2);
@@ -331,5 +370,5 @@ bool FbReadHandler::comment(const QString& ch)
 
 void FbReadHandler::addFile(const QString &name, const QByteArray &data)
 {
-    QMetaObject::invokeMethod(m_temp, "data", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QByteArray, data));
+    emit binary(name, data);
 }

+ 28 - 8
source/fb2read.hpp

@@ -8,8 +8,26 @@
 #include <QThread>
 #include <QXmlDefaultHandler>
 
-class FbTextPage;
+class FbReadThread : public QThread
+{
+    Q_OBJECT
+
+public:
+    FbReadThread(const QString &html, QObject *parent = 0);
+
+signals:
+    void html(const QString &html, const QUrl &url);
+
+protected:
+    void run();
 
+private:
+    const QString m_html;
+};
+
+
+class FbTextPage;
+/*
 class FbReadThread : public QThread
 {
     Q_OBJECT
@@ -19,7 +37,6 @@ public:
 
 public:
     void setPage(FbTextPage *page) { m_page = page; }
-    void setTemp(QObject *temp) { m_temp = temp; }
     FbTextPage * page() const { return m_page; }
     QObject * temp() const { return m_temp; }
     QString * data() { return &m_html; }
@@ -45,14 +62,16 @@ private:
     bool m_abort;
     QMutex mutex;
 };
-
-class FbReadHandler : public FbXmlHandler
+*/
+class FbReadHandler : public QObject, public FbXmlHandler
 {
+    Q_OBJECT
+
 public:
-    explicit FbReadHandler(FbReadThread &thread, QXmlStreamWriter &writer);
+    static bool load(QObject *page, QXmlInputSource &source, QString &html);
+    explicit FbReadHandler(QXmlStreamWriter &writer);
     virtual ~FbReadHandler();
     virtual bool comment(const QString& ch);
-    FbReadThread & thread() { return m_thread; }
     QXmlStreamWriter & writer() { return m_writer; }
 
 private:
@@ -142,6 +161,9 @@ private:
         QString m_text;
     };
 
+signals:
+    void binary(const QString &name, const QByteArray &data);
+
 protected:
     virtual NodeHandler * CreateRoot(const QString &name, const QXmlAttributes &atts);
 
@@ -150,9 +172,7 @@ private:
 
 private:
     typedef QHash<QString, QString> StringHash;
-    FbReadThread &m_thread;
     QXmlStreamWriter &m_writer;
-    QObject *m_temp;
     StringHash m_hash;
 };
 

+ 2 - 2
source/fb2temp.cpp

@@ -110,7 +110,7 @@ QByteArray FbTemporaryList::data(const QString &name) const
     return QByteArray();
 }
 
-const QString & FbTemporaryList::set(const QString &name, QByteArray &data, const QString &hash)
+const QString & FbTemporaryList::set(const QString &name, QByteArray data, const QString &hash)
 {
     FbTemporaryFile * file = get(name);
     if (!file) append(file = new FbTemporaryFile(name));
@@ -236,7 +236,7 @@ QByteArray FbNetworkAccessManager::data(int index) const
     return QByteArray();
 }
 
-void FbNetworkAccessManager::data(QString name, QByteArray data)
+void FbNetworkAccessManager::data(const QString &name, const QByteArray &data)
 {
     m_files.set(name, data);
 }

+ 2 - 2
source/fb2temp.hpp

@@ -43,7 +43,7 @@ public:
     QString add(const QString &path, QByteArray &data);
     bool exists(const QString &name) const;
     FbTemporaryFile * get(const QString &name) const;
-    const QString & set(const QString &name, QByteArray &data, const QString &hash = QString());
+    const QString & set(const QString &name, QByteArray data, const QString &hash = QString());
     QString name(const QString &hash) const;
     QByteArray data(const QString &name) const;
 private:
@@ -91,7 +91,7 @@ public:
     void setPath(const QString &path) { m_path = path; }
 
 public slots:
-    void data(QString name, QByteArray data);
+    void data(const QString &name, const QByteArray &data);
 
 public:
     QString add(const QString &path, QByteArray &data) { return m_files.add(path, data); }

+ 41 - 10
source/fb2text.cpp

@@ -106,6 +106,45 @@ FbNetworkAccessManager *FbTextPage::temp()
     return qobject_cast<FbNetworkAccessManager*>(networkAccessManager());
 }
 
+void FbTextPage::binary(const QString &name, const QByteArray &data)
+{
+    if (FbNetworkAccessManager *t = temp()) t->data(name, data);
+}
+
+bool FbTextPage::load(const QString &filename, const QString &xml)
+{
+    QXmlInputSource source;
+    if (xml.isEmpty()) {
+        QFile file(filename);
+        if (!file.open(QFile::ReadOnly | QFile::Text)) {
+            qCritical() << QObject::tr("Cannot read file %1: %2.").arg(filename).arg(file.errorString());
+            return false;
+        }
+        source.setData(file.readAll());
+    } else {
+        source.setData(xml);
+    }
+
+    bool ok = FbReadHandler::load(this, source, m_html);
+    if (ok) QTimer::singleShot(1000, this, SLOT(onTimer()));
+
+    return ok;
+}
+
+void FbTextPage::onTimer()
+{
+    static int number = 0;
+    QUrl url(QString("fb2:/%1/").arg(number++));
+    temp()->setPath(url.path());
+    mainFrame()->setHtml(m_html, url);
+}
+
+void FbTextPage::html(const QString &html, const QUrl &url)
+{
+    mainFrame()->setHtml(html, url);
+    temp()->setPath(url.path());
+}
+
 bool FbTextPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
 {
     Q_UNUSED(frame);
@@ -614,18 +653,9 @@ void FbTextEdit::linkHovered(const QString &link, const QString &title, const QS
     noteView().hint(element, QRect(point, size));
 }
 
-void FbTextEdit::load(const QString &filename, const QString &xml)
-{
-    if (m_thread) return;
-    m_thread = new FbReadThread(this, filename, xml);
-    FbTextPage *page = new FbTextPage(m_thread);
-    m_thread->setPage(page);
-    m_thread->setTemp(page->temp());
-    m_thread->start();
-}
-
 void FbTextEdit::html(QString html)
 {
+/*
     if (!m_thread) return;
     static int number = 0;
     QWebSettings::clearMemoryCaches();
@@ -638,6 +668,7 @@ void FbTextEdit::html(QString html)
     connect(page, SIGNAL(linkHovered(QString,QString,QString)), SLOT(linkHovered(QString,QString,QString)));
     m_thread->deleteLater();
     m_thread = 0;
+*/
 }
 
 bool FbTextEdit::save(QIODevice *device, const QString &codec)

+ 5 - 1
source/fb2text.hpp

@@ -79,6 +79,7 @@ class FbTextPage : public QWebPage
 public:
     explicit FbTextPage(QObject *parent = 0);
     FbNetworkAccessManager *temp();
+    bool load(const QString &filename, const QString &xml = QString());
     void push(QUndoCommand * command, const QString &text = QString());
     FbTextElement element(const QString &location);
     FbTextElement current();
@@ -92,6 +93,7 @@ public:
     FbTextElement appendTitle(const FbTextElement &parent);
 
 public slots:
+    void html(const QString &html, const QUrl &url);
     void insertBody();
     void insertTitle();
     void insertAnnot();
@@ -118,11 +120,14 @@ protected:
     void update();
 
 private slots:
+    void onTimer();
+    void binary(const QString &name, const QByteArray &data);
     void loadFinished();
     void fixContents();
 
 private:
     FbTextLogger m_logger;
+    QString m_html;
 };
 
 class FbTextEdit : public FbTextBase
@@ -135,7 +140,6 @@ public:
 
     FbTextPage *page();
     FbNetworkAccessManager *files();
-    void load(const QString &filename, const QString &xml = QString());
     bool save(QIODevice *device, const QString &codec = QString());
     bool save(QByteArray *array);
     bool save(QString *string);