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

FB2: process <section> element

Kandrashin Denis 13 лет назад
Родитель
Сommit
de25ce8571
4 измененных файлов с 130 добавлено и 31 удалено
  1. 5 3
      source/fb2edit.pro
  2. 3 1
      source/fb2main.cpp
  3. 89 17
      source/fb2read.cpp
  4. 33 10
      source/fb2read.h

+ 5 - 3
source/fb2edit.pro

@@ -1,11 +1,13 @@
-HEADERS       = \
+HEADERS = \
     fb2main.h \
     fb2main.h \
     fb2read.h
     fb2read.h
-SOURCES       = \
+
+SOURCES = \
     fb2app.cpp \
     fb2app.cpp \
     fb2main.cpp \
     fb2main.cpp \
     fb2read.cpp
     fb2read.cpp
-RESOURCES     = \
+
+RESOURCES = \
     fb2edit.qrc
     fb2edit.qrc
 
 
 QT += xml
 QT += xml

+ 3 - 1
source/fb2main.cpp

@@ -97,6 +97,8 @@ void MainWindow::init()
     isUntitled = true;
     isUntitled = true;
 
 
     textEdit = new QTextEdit;
     textEdit = new QTextEdit;
+    textEdit->setAcceptRichText(true);
+
     setCentralWidget(textEdit);
     setCentralWidget(textEdit);
 
 
     createActions();
     createActions();
@@ -274,7 +276,7 @@ void MainWindow::loadFile(const QString &fileName)
 
 
     QApplication::setOverrideCursor(Qt::WaitCursor);
     QApplication::setOverrideCursor(Qt::WaitCursor);
 
 
-    Fb2Reader handler(textEdit);
+    Fb2Handler handler(textEdit);
     QXmlSimpleReader reader;
     QXmlSimpleReader reader;
     reader.setContentHandler(&handler);
     reader.setContentHandler(&handler);
     reader.setErrorHandler(&handler);
     reader.setErrorHandler(&handler);

+ 89 - 17
source/fb2read.cpp

@@ -3,7 +3,34 @@
 
 
 #include "fb2read.h"
 #include "fb2read.h"
 
 
-Fb2Reader::Fb2Reader(QTextEdit * editor)
+Fb2Handler::SectionHash::SectionHash()
+{
+    insert("body", Body);
+    insert("descriptin", Descr);
+    insert("bynary", Bynary);
+}
+
+Fb2Handler::KeywordHash::KeywordHash()
+{
+    insert("image",   Image);
+    insert("p",       Paragraph);
+    insert("section", Section);
+    insert("title",   Title);
+}
+
+Fb2Handler::DocSection Fb2Handler::GetSection(const QString &name)
+{
+    static SectionHash map;
+    return map[name];
+}
+
+Fb2Handler::DocKeyword Fb2Handler::GetKeyword(const QString &name)
+{
+    static KeywordHash map;
+    return map[name];
+}
+
+Fb2Handler::Fb2Handler(QTextEdit * editor)
     : m_editor(editor)
     : m_editor(editor)
     , m_cursor(editor->textCursor())
     , m_cursor(editor->textCursor())
     , m_section(None)
     , m_section(None)
@@ -13,12 +40,12 @@ Fb2Reader::Fb2Reader(QTextEdit * editor)
     m_cursor.movePosition(QTextCursor::Start);
     m_cursor.movePosition(QTextCursor::Start);
 }
 }
 
 
-Fb2Reader::~Fb2Reader()
+Fb2Handler::~Fb2Handler()
 {
 {
     m_cursor.endEditBlock();
     m_cursor.endEditBlock();
 }
 }
 
 
-bool Fb2Reader::startElement(const QString & /* namespaceURI */,
+bool Fb2Handler::startElement(const QString & /* namespaceURI */,
                                const QString & /* localName */,
                                const QString & /* localName */,
                                const QString &qName,
                                const QString &qName,
                                const QXmlAttributes &attributes)
                                const QXmlAttributes &attributes)
@@ -33,18 +60,12 @@ bool Fb2Reader::startElement(const QString & /* namespaceURI */,
             };
             };
         } break;
         } break;
         case 1: {
         case 1: {
-            if (name == "body") {
-                m_section = Body;
-            } else if (name == "description") {
-                m_section = Descr;
-            } else if (name == "binary") {
-                m_section = Bynary;
-            } else {
-                m_section = None;
-            }
+                m_section = GetSection(name);
         } break;
         } break;
         default: {
         default: {
-            if (name == "p") m_cursor.insertBlock();
+            switch (m_section) {
+                case Body: BodyNew(name, attributes); break;
+            }
         } break;
         } break;
     }
     }
 
 
@@ -55,11 +76,19 @@ bool Fb2Reader::startElement(const QString & /* namespaceURI */,
     return true;
     return true;
 }
 }
 
 
-bool Fb2Reader::endElement(const QString & /* namespaceURI */,
+bool Fb2Handler::endElement(const QString & /* namespaceURI */,
                              const QString & /* localName */,
                              const QString & /* localName */,
                              const QString &qName)
                              const QString &qName)
 {
 {
     const QString name = qName.toLower();
     const QString name = qName.toLower();
+
+    if (name == "section") {
+        if (!m_frames.isEmpty()) {
+            m_cursor.setPosition(m_frames.last()->lastPosition());
+            m_frames.removeLast();
+        }
+    }
+
     int index = m_tags.lastIndexOf(name);
     int index = m_tags.lastIndexOf(name);
     int count = m_tags.count();
     int count = m_tags.count();
     for (int i = index; i < count; i++) m_tags.removeLast();
     for (int i = index; i < count; i++) m_tags.removeLast();
@@ -68,7 +97,7 @@ bool Fb2Reader::endElement(const QString & /* namespaceURI */,
     return true;
     return true;
 }
 }
 
 
-bool Fb2Reader::characters(const QString &str)
+bool Fb2Handler::characters(const QString &str)
 {
 {
     switch (m_section) {
     switch (m_section) {
         case Body: {
         case Body: {
@@ -81,7 +110,7 @@ bool Fb2Reader::characters(const QString &str)
     return true;
     return true;
 }
 }
 
 
-bool Fb2Reader::fatalError(const QXmlParseException &exception)
+bool Fb2Handler::fatalError(const QXmlParseException &exception)
 {
 {
     QMessageBox::information(
     QMessageBox::information(
         m_editor->window(),
         m_editor->window(),
@@ -94,13 +123,56 @@ bool Fb2Reader::fatalError(const QXmlParseException &exception)
     return false;
     return false;
 }
 }
 
 
-QString Fb2Reader::errorString() const
+QString Fb2Handler::errorString() const
 {
 {
     return m_error;
     return m_error;
 }
 }
 
 
+bool Fb2Handler::BodyNew(const QString &name, const QXmlAttributes &attributes)
+{
+    switch (GetKeyword(name)) {
+        case Paragraph: {
+            m_cursor.insertBlock();
+        } break;
+        case Section: {
+            m_frames << m_cursor.currentFrame();
+            QTextFrameFormat format;
+            format.setBorder(1);
+            format.setPadding(8);
+            m_cursor.insertFrame(format);
+        } break;
+        case Image: {
+            int count = attributes.count();
+            for (int i = 0; i < count; i++ ) {
+                if (attributes.localName(i).compare("href", Qt::CaseInsensitive) == 0) {
+                    QString image = attributes.value(i);
+                    while (image.left(1) == "#") image.remove(0, 1);
+                    m_cursor.insertImage(image);
+                    break;
+                }
+            }
+        } break;
+    }
+    return true;
+}
+
+bool Fb2Handler::BodyEnd(const QString &name)
+{
+    return true;
+}
+
 /*
 /*
 
 
+    QMessageBox::information(
+        m_editor->window(),
+        QObject::tr("fb2edit"),
+        QObject::tr("%1=%2\n%1=%3")
+            .arg(attributes.localName(i))
+            .arg(attributes.value(i))
+            .arg(image)
+        );
+
+
 //! [2]
 //! [2]
     QTextCursor cursor(editor->textCursor());
     QTextCursor cursor(editor->textCursor());
     cursor.movePosition(QTextCursor::Start);
     cursor.movePosition(QTextCursor::Start);

+ 33 - 10
source/fb2read.h

@@ -9,29 +9,52 @@ QT_BEGIN_NAMESPACE
 class QTextEdit;
 class QTextEdit;
 QT_END_NAMESPACE
 QT_END_NAMESPACE
 
 
-class Fb2Reader : public QXmlDefaultHandler
+class Fb2Handler : public QXmlDefaultHandler
 {
 {
 public:
 public:
-    enum DocumentSection {
-        None   = 0x0000,
-        Body   = 0x0001,
-        Descr  = 0x0002,
-        Bynary = 0x0003,
-    };
-    Fb2Reader(QTextEdit * editor);
-    virtual ~Fb2Reader();
+    Fb2Handler(QTextEdit * editor);
+    virtual ~Fb2Handler();
     bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &attributes);
     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);
     bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName);
     bool characters(const QString &str);
     bool characters(const QString &str);
     bool fatalError(const QXmlParseException &exception);
     bool fatalError(const QXmlParseException &exception);
     QString errorString() const;
     QString errorString() const;
+
+private:
+    enum DocSection {
+        None   = 0x0000,
+        Body   = 0x0001,
+        Descr  = 0x0002,
+        Bynary = 0x0003,
+    };
+
+    enum DocKeyword {
+        Image,
+        Paragraph,
+        Section,
+        Title,
+    };
+
+    class SectionHash : public QHash<QString, DocSection> { public: SectionHash(); };
+
+    class KeywordHash : public QHash<QString, DocKeyword> { public: KeywordHash(); };
+
+    static DocSection GetSection(const QString &name);
+
+    static DocKeyword GetKeyword(const QString &name);
+
+private:
+    bool BodyNew(const QString &name, const QXmlAttributes &attributes);
+    bool BodyEnd(const QString &name);
+
 private:
 private:
     QTextEdit * m_editor;
     QTextEdit * m_editor;
     QTextCursor m_cursor;
     QTextCursor m_cursor;
     QString m_text;
     QString m_text;
     QString m_error;
     QString m_error;
     QStringList m_tags;
     QStringList m_tags;
-    DocumentSection m_section;
+    DocSection m_section;
+    QList<QTextFrame*> m_frames;
 };
 };
 
 
 #endif // FB2READ_H
 #endif // FB2READ_H