瀏覽代碼

Fix main menu, remove class Fb2ReadWriter

Kandrashin Denis 13 年之前
父節點
當前提交
3906b9b91d
共有 5 個文件被更改,包括 213 次插入157 次删除
  1. 106 45
      source/fb2main.cpp
  2. 2 0
      source/fb2main.h
  3. 78 85
      source/fb2read.cpp
  4. 25 27
      source/fb2read.h
  5. 2 0
      source/fb2xml.h

+ 106 - 45
source/fb2main.cpp

@@ -257,7 +257,80 @@ void Fb2MainWindow::createActions()
     menu->addAction(act);
 
     menuEdit = menu = menuBar()->addMenu(tr("&Edit"));
+
+    connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
+
+    actionUndo = act = new QAction(icon("edit-undo"), tr("&Undo"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcut(QKeySequence::Undo);
+    act->setEnabled(false);
+    menu->addAction(act);
+
+    actionRedo = act = new QAction(icon("edit-redo"), tr("&Redo"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcut(QKeySequence::Redo);
+    act->setEnabled(false);
+    menu->addAction(act);
+
+    menu->addSeparator();
+
+    actionCut = act = new QAction(icon("edit-cut"), tr("Cu&t"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcuts(QKeySequence::Cut);
+    act->setStatusTip(tr("Cut the current selection's contents to the clipboard"));
+    act->setEnabled(false);
+    menu->addAction(act);
+
+    actionCopy = act = new QAction(icon("edit-copy"), tr("&Copy"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcuts(QKeySequence::Copy);
+    act->setStatusTip(tr("Copy the current selection's contents to the clipboard"));
+    act->setEnabled(false);
+    menu->addAction(act);
+
+    actionPaste = act = new QAction(icon("edit-paste"), tr("&Paste"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcuts(QKeySequence::Paste);
+    act->setStatusTip(tr("Paste the clipboard's contents into the current selection"));
+    menu->addAction(act);
+    clipboardDataChanged();
+
+    menu->addSeparator();
+
+    actionInsert = act = new QAction(icon("list-add"), tr("Insert"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcuts(QKeySequence::New);
+    menu->addAction(act);
+
+    actionDelete = act = new QAction(icon("list-remove"), tr("Delete"), this);
+    act->setPriority(QAction::LowPriority);
+    act->setShortcuts(QKeySequence::Delete);
+    menu->addAction(act);
+
     menuText = menu = menuBar()->addMenu(tr("Fo&rmat"));
+
+    actionTextBold = act = new QAction(icon("format-text-bold"), tr("Bold"), this);
+    act->setShortcuts(QKeySequence::Bold);
+    act->setCheckable(true);
+    menu->addAction(act);
+
+    actionTextItalic = act = new QAction(icon("format-text-italic"), tr("Italic"), this);
+    act->setShortcuts(QKeySequence::Italic);
+    act->setCheckable(true);
+    menu->addAction(act);
+
+    actionTextStrike = act = new QAction(icon("format-text-strikethrough"), tr("Strikethrough"), this);
+    act->setCheckable(true);
+    menu->addAction(act);
+
+    actionTextSup = act = new QAction(icon("format-text-superscript"), tr("Superscript"), this);
+    act->setCheckable(true);
+    menu->addAction(act);
+
+    actionTextSub = act = new QAction(icon("format-text-subscript"), tr("Subscript"), this);
+    act->setCheckable(true);
+    menu->addAction(act);
+
     menuView = menu = menuBar()->addMenu(tr("&View"));
 
     tool->addSeparator();
@@ -342,6 +415,7 @@ void Fb2MainWindow::createHead()
 {
     if (headTree) return;
     headTree = new QTreeView(this);
+    headTree->header()->setDefaultSectionSize(200);
     if (textEdit) {
         this->setFocus();
         textEdit->setParent(NULL);
@@ -528,8 +602,6 @@ void Fb2MainWindow::viewQsci()
     FB2DELETE(dockTree);
     FB2DELETE(headTree);
     FB2DELETE(toolEdit);
-    menuEdit->clear();
-    menuText->clear();
     createQsci();
     qsciEdit->setText(xml);
 }
@@ -546,35 +618,41 @@ void Fb2MainWindow::viewText()
     textEdit->setFocus();
     viewTree();
 
-    //    connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged()));
-
     connect(textEdit->page(), SIGNAL(contentsChanged()), SLOT(documentWasModified()));
     connect(textEdit, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
     connect(textEdit, SIGNAL(loadFinished(bool)), SLOT(loadFinished(bool)));
 
+    connect(textEdit->pageAction(QWebPage::Undo), SIGNAL(changed()), SLOT(undoChanged()));
+    connect(textEdit->pageAction(QWebPage::Redo), SIGNAL(changed()), SLOT(redoChanged()));
+    connect(actionUndo, SIGNAL(triggered()), textEdit->pageAction(QWebPage::Undo), SIGNAL(triggered()));
+    connect(actionRedo, SIGNAL(triggered()), textEdit->pageAction(QWebPage::Redo), SIGNAL(triggered()));
+
+    connect(actionCut, SIGNAL(triggered()), textEdit->pageAction(QWebPage::Cut), SIGNAL(triggered()));
+    connect(actionCopy, SIGNAL(triggered()), textEdit->pageAction(QWebPage::Copy), SIGNAL(triggered()));
+    connect(actionPaste, SIGNAL(triggered()), textEdit->pageAction(QWebPage::Paste), SIGNAL(triggered()));
+
+    connect(actionTextBold, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleBold), SIGNAL(triggered()));
+    connect(actionTextItalic, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleItalic), SIGNAL(triggered()));
+    connect(actionTextStrike, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleStrikethrough), SIGNAL(triggered()));
+    connect(actionTextSub, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleSubscript), SIGNAL(triggered()));
+    connect(actionTextSup, SIGNAL(triggered()), textEdit->pageAction(QWebPage::ToggleSuperscript), SIGNAL(triggered()));
+
     connect(actionZoomIn, SIGNAL(triggered()), textEdit, SLOT(zoomIn()));
     connect(actionZoomOut, SIGNAL(triggered()), textEdit, SLOT(zoomOut()));
     connect(actionZoomOrig, SIGNAL(triggered()), textEdit, SLOT(zoomOrig()));
 
-    menuEdit->clear();
-    menuText->clear();
-
     FB2DELETE(toolEdit);
     QToolBar *tool = toolEdit = addToolBar(tr("Edit"));
     tool->setMovable(false);
     tool->addSeparator();
 
     QAction *act;
-    QMenu *menu;
-
-    menu = menuEdit;
 
     act = textEdit->pageAction(QWebPage::Undo);
     act->setIcon(icon("edit-undo"));
     act->setText(tr("&Undo"));
     act->setPriority(QAction::LowPriority);
     act->setShortcut(QKeySequence::Undo);
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::Redo);
@@ -582,10 +660,8 @@ void Fb2MainWindow::viewText()
     act->setText(tr("&Redo"));
     act->setPriority(QAction::LowPriority);
     act->setShortcut(QKeySequence::Redo);
-    menu->addAction(act);
     tool->addAction(act);
 
-    menu->addSeparator();
     tool->addSeparator();
 
     act = textEdit->pageAction(QWebPage::Cut);
@@ -594,7 +670,6 @@ void Fb2MainWindow::viewText()
     act->setPriority(QAction::LowPriority);
     act->setShortcuts(QKeySequence::Cut);
     act->setStatusTip(tr("Cut the current selection's contents to the clipboard"));
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::Copy);
@@ -603,7 +678,6 @@ void Fb2MainWindow::viewText()
     act->setPriority(QAction::LowPriority);
     act->setShortcuts(QKeySequence::Copy);
     act->setStatusTip(tr("Copy the current selection's contents to the clipboard"));
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::Paste);
@@ -612,43 +686,35 @@ void Fb2MainWindow::viewText()
     act->setPriority(QAction::LowPriority);
     act->setShortcuts(QKeySequence::Paste);
     act->setStatusTip(tr("Paste the clipboard's contents into the current selection"));
-    menu->addAction(act);
     tool->addAction(act);
 
     tool->addSeparator();
 
-    menu = menuText;
-
     act = textEdit->pageAction(QWebPage::ToggleBold);
     act->setIcon(icon("format-text-bold"));
     act->setText(tr("&Bold"));
     act->setShortcuts(QKeySequence::Bold);
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::ToggleItalic);
     act->setIcon(icon("format-text-italic"));
     act->setText(tr("&Italic"));
     act->setShortcuts(QKeySequence::Italic);
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::ToggleStrikethrough);
     act->setIcon(icon("format-text-strikethrough"));
     act->setText(tr("&Strikethrough"));
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::ToggleSuperscript);
     act->setIcon(icon("format-text-superscript"));
     act->setText(tr("Superscript"));
-    menu->addAction(act);
     tool->addAction(act);
 
     act = textEdit->pageAction(QWebPage::ToggleSubscript);
     act->setIcon(icon("format-text-subscript"));
     act->setText(tr("Subscript"));
-    menu->addAction(act);
     tool->addAction(act);
 
     tool->addSeparator();
@@ -656,9 +722,6 @@ void Fb2MainWindow::viewText()
     tool->addAction(actionZoomIn);
     tool->addAction(actionZoomOut);
     tool->addAction(actionZoomOrig);
-
-    act = textEdit->pageAction(QWebPage::InspectElement);
-    menuView->addAction(act);
 }
 
 void Fb2MainWindow::viewHead()
@@ -667,29 +730,29 @@ void Fb2MainWindow::viewHead()
     FB2DELETE(dockTree);
     FB2DELETE(qsciEdit);
     FB2DELETE(toolEdit);
-    menuEdit->clear();
-    menuText->clear();
     createHead();
 
+    if (textEdit) {
+        actionUndo->disconnect();
+        actionRedo->disconnect();
+
+        actionCut->disconnect();
+        actionCopy->disconnect();
+        actionPaste->disconnect();
+
+        actionTextBold->disconnect();
+        actionTextItalic->disconnect();
+        actionTextStrike->disconnect();
+        actionTextSub->disconnect();
+        actionTextSup->disconnect();
+    }
+
     FB2DELETE(toolEdit);
     QToolBar *tool = toolEdit = addToolBar(tr("Edit"));
+    tool->addAction(actionInsert);
+    tool->addAction(actionDelete);
     tool->setMovable(false);
     tool->addSeparator();
-
-    QAction *act;
-    QMenu *menu = menuEdit;
-
-    act = new QAction(icon("list-add"), tr("Insert"), this);
-    act->setPriority(QAction::LowPriority);
-    act->setShortcuts(QKeySequence::New);
-    menu->addAction(act);
-    tool->addAction(act);
-
-    act = new QAction(icon("list-remove"), tr("Delete"), this);
-    act->setPriority(QAction::LowPriority);
-    act->setShortcuts(QKeySequence::Delete);
-    menu->addAction(act);
-    tool->addAction(act);
 }
 
 void Fb2MainWindow::viewTree()
@@ -701,11 +764,9 @@ void Fb2MainWindow::viewTree()
 
 void Fb2MainWindow::clipboardDataChanged()
 {
-/*
     if (const QMimeData *md = QApplication::clipboard()->mimeData()) {
         actionPaste->setEnabled(md->hasText());
     }
-*/
 }
 
 void Fb2MainWindow::showInspector()

+ 2 - 0
source/fb2main.h

@@ -102,6 +102,8 @@ private:
         *actionCopy,
         *actionPaste,
         *actionSelect,
+        *actionInsert,
+        *actionDelete,
         *actionTextBold,
         *actionTextItalic,
         *actionTextStrike,

+ 78 - 85
source/fb2read.cpp

@@ -41,43 +41,14 @@ bool Fb2ReadThread::parse()
         qCritical() << QObject::tr("Cannot read file %1: %2.").arg(m_filename).arg(file.errorString());
         return false;
     }
-    Fb2ReadHandler handler(*this);
+    QXmlStreamWriter writer(&m_html);
+    Fb2ReadHandler handler(*this, writer);
     XML2::XmlReader reader;
     reader.setContentHandler(&handler);
     reader.setErrorHandler(&handler);
     return reader.parse(file);
 }
 
-//---------------------------------------------------------------------------
-//  Fb2ReadWriter
-//---------------------------------------------------------------------------
-
-Fb2ReadWriter::Fb2ReadWriter(Fb2ReadThread &thread)
-    : QXmlStreamWriter(thread.data())
-    , m_thread(thread)
-    , m_id(0)
-{
-    setAutoFormatting(true);
-    setAutoFormattingIndent(2);
-}
-
-QString Fb2ReadWriter::getFile(const QString &name)
-{
-    QString path;
-    QMetaObject::invokeMethod(m_thread.parent(), "temp", Qt::DirectConnection, Q_RETURN_ARG(QString, path), Q_ARG(QString, name));
-    return path;
-}
-
-void Fb2ReadWriter::addFile(const QString &name, const QByteArray &data)
-{
-    QMetaObject::invokeMethod(m_thread.parent(), "data", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QByteArray, data));
-}
-
-QString Fb2ReadWriter::newId()
-{
-    return QString("FB2E%1").arg(++m_id);
-}
-
 //---------------------------------------------------------------------------
 //  Fb2ReadHandler::RootHandler
 //---------------------------------------------------------------------------
@@ -89,20 +60,20 @@ FB2_BEGIN_KEYHASH(Fb2ReadHandler::RootHandler)
     FB2_KEY( Binary , "binary"      );
 FB2_END_KEYHASH
 
-Fb2ReadHandler::RootHandler::RootHandler(Fb2ReadWriter &writer, const QString &name)
-    : BaseHandler(writer, name)
+Fb2ReadHandler::RootHandler::RootHandler(Fb2ReadHandler &owner, const QString &name)
+    : BaseHandler(owner, name)
 {
-    m_writer.writeStartDocument();
-    m_writer.writeStartElement("html");
-    m_writer.writeStartElement("body");
+    writer().writeStartDocument();
+    writer().writeStartElement("html");
+    writer().writeStartElement("body");
 }
 
 Fb2XmlHandler::NodeHandler * Fb2ReadHandler::RootHandler::NewTag(const QString &name, const QXmlAttributes &atts)
 {
     switch (toKeyword(name)) {
-        case Body   : return new TextHandler(m_writer, name, atts, "div", name);
-        case Descr  : return new DescrHandler(m_writer, name, atts);
-        case Binary : return new BinaryHandler(m_writer, name, atts);
+        case Body   : return new TextHandler(m_owner, name, atts, "div", name);
+        case Descr  : return new DescrHandler(m_owner, name, atts);
+        case Binary : return new BinaryHandler(m_owner, name, atts);
         default: return NULL;
     }
 }
@@ -110,9 +81,9 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::RootHandler::NewTag(const QString &
 void Fb2ReadHandler::RootHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
-    m_writer.writeEndElement();
-    m_writer.writeEndElement();
-    m_writer.writeEndDocument();
+    writer().writeEndElement();
+    writer().writeEndElement();
+    writer().writeEndDocument();
 }
 
 //---------------------------------------------------------------------------
@@ -123,15 +94,15 @@ FB2_BEGIN_KEYHASH(Fb2ReadHandler::HeadHandler)
     FB2_KEY( Image , "image" );
 FB2_END_KEYHASH
 
-Fb2ReadHandler::HeadHandler::HeadHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts)
-    : BaseHandler(writer, name)
+Fb2ReadHandler::HeadHandler::HeadHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts)
+    : BaseHandler(owner, name)
     , m_empty(true)
 {
-    m_writer.writeStartElement("div");
-    m_writer.writeAttribute("class", name);
+    writer().writeStartElement("div");
+    writer().writeAttribute("class", name);
     int count = atts.count();
     for (int i = 0; i < count; i++) {
-        m_writer.writeAttribute("fb2:" + atts.qName(i), atts.value(i));
+        writer().writeAttribute("fb2:" + atts.qName(i), atts.value(i));
     }
 }
 
@@ -140,22 +111,22 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::HeadHandler::NewTag(const QString &
     Q_UNUSED(atts);
     m_empty = false;
     switch (toKeyword(name)) {
-        case Image: return new ImageHandler(m_writer, name, atts);
-        default: return new HeadHandler(m_writer, name, atts);
+        case Image: return new ImageHandler(m_owner, name, atts);
+        default: return new HeadHandler(m_owner, name, atts);
     }
 }
 
 void Fb2ReadHandler::HeadHandler::TxtTag(const QString &text)
 {
     m_empty = false;
-    m_writer.writeCharacters(text);
+    writer().writeCharacters(text);
 }
 
 void Fb2ReadHandler::HeadHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
-    if (m_empty) m_writer.writeCharacters(" ");
-    m_writer.writeEndElement();
+    if (m_empty) writer().writeCharacters(" ");
+    writer().writeEndElement();
 }
 
 //---------------------------------------------------------------------------
@@ -169,10 +140,10 @@ FB2_BEGIN_KEYHASH(Fb2ReadHandler::DescrHandler)
     FB2_KEY( Custom   , "custom-info"   );
 FB2_END_KEYHASH
 
-Fb2ReadHandler::DescrHandler::DescrHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts)
-    : HeadHandler(writer, name, atts)
+Fb2ReadHandler::DescrHandler::DescrHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts)
+    : HeadHandler(owner, name, atts)
 {
-    m_writer.writeAttribute("id", m_writer.newId());
+    writer().writeAttribute("id", m_owner.newId());
 }
 
 Fb2XmlHandler::NodeHandler * Fb2ReadHandler::DescrHandler::NewTag(const QString &name, const QXmlAttributes &atts)
@@ -180,11 +151,11 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::DescrHandler::NewTag(const QString
     Q_UNUSED(atts);
     switch (toKeyword(name)) {
         case Title :
-            return new TitleHandler(m_writer, name, atts);
+            return new TitleHandler(m_owner, name, atts);
         case Document :
         case Publish :
         case Custom :
-            return new HeadHandler(m_writer, name, atts);
+            return new HeadHandler(m_owner, name, atts);
         default:
             return NULL;
     }
@@ -194,16 +165,16 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::DescrHandler::NewTag(const QString
 //  Fb2ReadHandler::TitleHandler
 //---------------------------------------------------------------------------
 
-Fb2ReadHandler::TitleHandler::TitleHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts)
-    : HeadHandler(writer, name, atts)
+Fb2ReadHandler::TitleHandler::TitleHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts)
+    : HeadHandler(owner, name, atts)
 {
-    m_writer.writeAttribute("id", m_writer.newId());
+    writer().writeAttribute("id", m_owner.newId());
 }
 
 Fb2XmlHandler::NodeHandler * Fb2ReadHandler::TitleHandler::NewTag(const QString &name, const QXmlAttributes &atts)
 {
-    if (name == "annotation") return new TextHandler(m_writer, name, atts, "div", name);
-    return new HeadHandler(m_writer, name, atts);
+    if (name == "annotation") return new TextHandler(m_owner, name, atts, "div", name);
+    return new HeadHandler(m_owner, name, atts);
 }
 
 //---------------------------------------------------------------------------
@@ -239,8 +210,8 @@ FB2_BEGIN_KEYHASH(Fb2ReadHandler::TextHandler)
     FB2_KEY( Code    , "code"          );
 FB2_END_KEYHASH
 
-Fb2ReadHandler::TextHandler::TextHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag, const QString &style)
-    : BaseHandler(writer, name)
+Fb2ReadHandler::TextHandler::TextHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts, const QString &tag, const QString &style)
+    : BaseHandler(owner, name)
     , m_parent(NULL)
     , m_tag(tag)
     , m_style(style)
@@ -249,7 +220,7 @@ Fb2ReadHandler::TextHandler::TextHandler(Fb2ReadWriter &writer, const QString &n
 }
 
 Fb2ReadHandler::TextHandler::TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag, const QString &style)
-    : BaseHandler(parent->m_writer, name)
+    : BaseHandler(parent->m_owner, name)
     , m_parent(parent)
     , m_tag(tag)
     , m_style(style)
@@ -260,17 +231,17 @@ Fb2ReadHandler::TextHandler::TextHandler(TextHandler *parent, const QString &nam
 void Fb2ReadHandler::TextHandler::Init(const QXmlAttributes &atts)
 {
     if (m_tag.isEmpty()) return;
-    m_writer.writeStartElement(m_tag);
+    writer().writeStartElement(m_tag);
     QString id = Value(atts, "id");
     if (!id.isEmpty()) {
         if (m_style == "section" && isNotes()) m_style = "note";
-        m_writer.writeAttribute("id", id);
+        writer().writeAttribute("id", id);
     } else if (m_tag == "div" || m_tag == "img") {
-        m_writer.writeAttribute("id", m_writer.newId());
+        writer().writeAttribute("id", m_owner.newId());
     }
     if (!m_style.isEmpty()) {
         if (m_style == "body" && Value(atts, "name").toLower() == "notes") m_style = "notes";
-        m_writer.writeAttribute("class", m_style);
+        writer().writeAttribute("class", m_style);
     }
 }
 
@@ -279,7 +250,7 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::TextHandler::NewTag(const QString &
     QString tag, style;
     switch (toKeyword(name)) {
         case Anchor    : return new AnchorHandler(this, name, atts);
-        case Image     : return new ImageHandler(m_writer, name, atts);
+        case Image     : return new ImageHandler(m_owner, name, atts);
         case Section   : tag = "div"; style = name; break;
         case Parag     : tag = "p";   break;
         case Strong    : tag = "b";   break;
@@ -295,15 +266,15 @@ Fb2XmlHandler::NodeHandler * Fb2ReadHandler::TextHandler::NewTag(const QString &
 
 void Fb2ReadHandler::TextHandler::TxtTag(const QString &text)
 {
-    m_writer.writeCharacters(text);
+    writer().writeCharacters(text);
 }
 
 void Fb2ReadHandler::TextHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
     if (m_tag.isEmpty()) return;
-    if (m_tag == "div") m_writer.writeCharacters(" ");
-    m_writer.writeEndElement();
+    if (m_tag == "div") writer().writeCharacters(" ");
+    writer().writeEndElement();
 }
 
 bool Fb2ReadHandler::TextHandler::isNotes() const
@@ -320,29 +291,29 @@ Fb2ReadHandler::AnchorHandler::AnchorHandler(TextHandler *parent, const QString
     : TextHandler(parent, name, atts, "a")
 {
     QString href = Value(atts, "href");
-    m_writer.writeAttribute("href", href);
+    writer().writeAttribute("href", href);
 }
 
 //---------------------------------------------------------------------------
 //  Fb2ReadHandler::ImageHandler
 //---------------------------------------------------------------------------
 
-Fb2ReadHandler::ImageHandler::ImageHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts)
-    : TextHandler(writer, name, atts, "img")
+Fb2ReadHandler::ImageHandler::ImageHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts)
+    : TextHandler(owner, name, atts, "img")
 {
     QString href = Value(atts, "href");
     while (href.left(1) == "#") href.remove(0, 1);
-    QString path = m_writer.getFile(href);
-    m_writer.writeAttribute("src", path);
-    m_writer.writeAttribute("alt", href);
+    QString path = m_owner.getFile(href);
+    writer().writeAttribute("src", path);
+    writer().writeAttribute("alt", href);
 }
 
 //---------------------------------------------------------------------------
 //  Fb2ReadHandler::BinaryHandler
 //---------------------------------------------------------------------------
 
-Fb2ReadHandler::BinaryHandler::BinaryHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts)
-    : BaseHandler(writer, name)
+Fb2ReadHandler::BinaryHandler::BinaryHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts)
+    : BaseHandler(owner, name)
     , m_file(Value(atts, "id"))
 {
 }
@@ -356,7 +327,7 @@ void Fb2ReadHandler::BinaryHandler::EndTag(const QString &name)
 {
     Q_UNUSED(name);
     QByteArray in; in.append(m_text);
-    if (!m_file.isEmpty()) m_writer.addFile(m_file, QByteArray::fromBase64(in));
+    if (!m_file.isEmpty()) m_owner.addFile(m_file, QByteArray::fromBase64(in));
 }
 
 
@@ -364,16 +335,38 @@ void Fb2ReadHandler::BinaryHandler::EndTag(const QString &name)
 //  Fb2ReadHandler
 //---------------------------------------------------------------------------
 
-Fb2ReadHandler::Fb2ReadHandler(Fb2ReadThread &thread)
+Fb2ReadHandler::Fb2ReadHandler(Fb2ReadThread &thread, QXmlStreamWriter &writer)
     : Fb2XmlHandler()
-    , m_writer(thread)
+    , m_thread(thread)
+    , m_writer(writer)
+    , m_id(0)
 {
+    m_writer.setAutoFormatting(true);
+    m_writer.setAutoFormattingIndent(2);
 }
 
 Fb2XmlHandler::NodeHandler * Fb2ReadHandler::CreateRoot(const QString &name, const QXmlAttributes &atts)
 {
     Q_UNUSED(atts);
-    if (name == "fictionbook") return new RootHandler(m_writer, name);
+    if (name == "fictionbook") return new RootHandler(*this, name);
     m_error = QObject::tr("The file is not an FB2 file.");
     return 0;
 }
+
+QString Fb2ReadHandler::getFile(const QString &name)
+{
+    QString path;
+    QMetaObject::invokeMethod(m_thread.parent(), "temp", Qt::DirectConnection, Q_RETURN_ARG(QString, path), Q_ARG(QString, name));
+    return path;
+}
+
+void Fb2ReadHandler::addFile(const QString &name, const QByteArray &data)
+{
+    QMetaObject::invokeMethod(m_thread.parent(), "data", Qt::QueuedConnection, Q_ARG(QString, name), Q_ARG(QByteArray, data));
+}
+
+QString Fb2ReadHandler::newId()
+{
+    return QString("FB2E%1").arg(++m_id);
+}
+

+ 25 - 27
source/fb2read.h

@@ -7,7 +7,6 @@
 #include <QMutex>
 #include <QThread>
 #include <QXmlDefaultHandler>
-#include <QXmlStreamWriter>
 
 class Fb2ReadThread : public QThread
 {
@@ -37,33 +36,23 @@ private:
     QMutex mutex;
 };
 
-class Fb2ReadWriter : public QXmlStreamWriter
-{
-public:
-    explicit Fb2ReadWriter(Fb2ReadThread &thread);
-    void addFile(const QString &name, const QByteArray &data);
-    QString getFile(const QString &name);
-    QString newId();
-private:
-    typedef QHash<QString, QString> StringHash;
-    Fb2ReadThread &m_thread;
-    StringHash m_hash;
-    int m_id;
-};
-
 class Fb2ReadHandler : public Fb2XmlHandler
 {
 public:
-    explicit Fb2ReadHandler(Fb2ReadThread &thread);
+    explicit Fb2ReadHandler(Fb2ReadThread &thread, QXmlStreamWriter &writer);
+    Fb2ReadThread & thread() { return m_thread; }
+    QXmlStreamWriter & writer() { return m_writer; }
 
 private:
     class BaseHandler : public NodeHandler
     {
     public:
-        explicit BaseHandler(Fb2ReadWriter &writer, const QString &name)
-            : NodeHandler(name), m_writer(writer) {}
+        explicit BaseHandler(Fb2ReadHandler &owner, const QString &name)
+            : NodeHandler(name), m_owner(owner) {}
+    protected:
+        QXmlStreamWriter & writer() { return m_owner.writer(); }
     protected:
-        Fb2ReadWriter &m_writer;
+        Fb2ReadHandler &m_owner;
     };
 
     class RootHandler : public BaseHandler
@@ -75,7 +64,7 @@ private:
             Binary,
         FB2_END_KEYLIST
     public:
-        explicit RootHandler(Fb2ReadWriter &writer, const QString &name);
+        explicit RootHandler(Fb2ReadHandler &owner, const QString &name);
     protected:
         virtual NodeHandler * NewTag(const QString & name, const QXmlAttributes &atts);
         virtual void EndTag(const QString &name);
@@ -87,7 +76,7 @@ private:
             Image,
         FB2_END_KEYLIST
     public:
-        explicit HeadHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts);
+        explicit HeadHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
         virtual void TxtTag(const QString &text);
@@ -105,7 +94,7 @@ private:
             Custom,
         FB2_END_KEYLIST
     public:
-        explicit DescrHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts);
+        explicit DescrHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
     };
@@ -113,7 +102,7 @@ private:
     class TitleHandler : public HeadHandler
     {
     public:
-        explicit TitleHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts);
+        explicit TitleHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
     };
@@ -135,7 +124,7 @@ private:
             Code,
        FB2_END_KEYLIST
     public:
-        explicit TextHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts, const QString &tag, const QString &style = QString());
+        explicit TextHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts, const QString &tag, const QString &style = QString());
         explicit TextHandler(TextHandler *parent, const QString &name, const QXmlAttributes &atts, const QString &tag, const QString &style = QString());
     protected:
         virtual NodeHandler * NewTag(const QString &name, const QXmlAttributes &atts);
@@ -159,13 +148,13 @@ private:
     class ImageHandler : public TextHandler
     {
     public:
-        explicit ImageHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts);
+        explicit ImageHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts);
     };
 
     class BinaryHandler : public BaseHandler
     {
     public:
-        explicit BinaryHandler(Fb2ReadWriter &writer, const QString &name, const QXmlAttributes &atts);
+        explicit BinaryHandler(Fb2ReadHandler &owner, const QString &name, const QXmlAttributes &atts);
     protected:
         virtual void TxtTag(const QString &text);
         virtual void EndTag(const QString &name);
@@ -178,7 +167,16 @@ protected:
     virtual NodeHandler * CreateRoot(const QString &name, const QXmlAttributes &atts);
 
 private:
-    Fb2ReadWriter m_writer;
+    void addFile(const QString &name, const QByteArray &data);
+    QString getFile(const QString &name);
+    QString newId();
+
+private:
+    typedef QHash<QString, QString> StringHash;
+    Fb2ReadThread &m_thread;
+    QXmlStreamWriter &m_writer;
+    StringHash m_hash;
+    int m_id;
 };
 
 #endif // FB2READ_H

+ 2 - 0
source/fb2xml.h

@@ -3,6 +3,8 @@
 
 #include <QHash>
 #include <QXmlDefaultHandler>
+#include <QXmlStreamReader>
+#include <QXmlStreamWriter>
 
 #define FB2_BEGIN_KEYLIST private: enum Keyword {