1
0
Эх сурвалжийг харах

New tools for inserting Fb2TextElement

Kandrashin Denis 13 жил өмнө
parent
commit
42683d0e97
2 өөрчлөгдсөн 119 нэмэгдсэн , 33 устгасан
  1. 93 24
      source/fb2html.cpp
  2. 26 9
      source/fb2html.h

+ 93 - 24
source/fb2html.cpp

@@ -3,52 +3,92 @@
 #include "fb2text.hpp"
 #include "fb2text.hpp"
 
 
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
-//  FbTextScheme
+//  FbTextElement::Scheme
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 
 
-FbTextScheme::FbTextScheme()
+FbTextElement::Scheme::Scheme()
 {
 {
     m_types["body"]
     m_types["body"]
-            << Type("image")
-            << Type("title")
-            << Type("epigraph", 0, 0)
-            << Type()
+        << Type("image")
+        << Type("title")
+        << Type("epigraph", 0, 0)
+        << Type()
     ;
     ;
 
 
     m_types["section"]
     m_types["section"]
-            << Type("title")
-            << Type("epigraph", 0, 0)
-            << Type("image")
-            << Type("annotation")
-            << Type()
+        << Type("title")
+        << Type("epigraph", 0, 0)
+        << Type("image")
+        << Type("annotation")
+        << Type()
     ;
     ;
 
 
     m_types["poem"]
     m_types["poem"]
-            << Type("title")
-            << Type("epigraph", 0, 0)
-            << Type("stanza", 1, 0)
-            << Type()
-            << Type("text-author", 0, 0)
-            << Type("date")
+        << Type("title")
+        << Type("epigraph", 0, 0)
+        << Type("stanza", 1, 0)
+        << Type()
+        << Type("text-author", 0, 0)
+        << Type("date")
     ;
     ;
 
 
     m_types["stanza"]
     m_types["stanza"]
-            << Type("title")
-            << Type("subtitle")
-            << Type()
+        << Type("title")
+        << Type("subtitle")
+        << Type()
     ;
     ;
 
 
     m_types["epigraph"]
     m_types["epigraph"]
-            << Type()
-            << Type("text-author", 0, 0)
+        << Type()
+        << Type("text-author", 0, 0)
     ;
     ;
 
 
     m_types["cite"]
     m_types["cite"]
-            << Type()
-            << Type("text-author", 0, 0)
+        << Type()
+        << Type("text-author", 0, 0)
     ;
     ;
 }
 }
 
 
+const FbTextElement::TypeList * FbTextElement::Scheme::operator[](const QString &name) const
+{
+    TypeMap::const_iterator it = m_types.find(name);
+    if (it != m_types.end()) return &it.value();
+    return 0;
+}
+
+//---------------------------------------------------------------------------
+//  FbTextElement::Sublist
+//---------------------------------------------------------------------------
+
+FbTextElement::Sublist::Sublist(const TypeList &list, const QString &name)
+    : m_list(list)
+    , m_pos(list.begin())
+{
+    while (m_pos != list.end()) {
+        if (m_pos->name() == name) break;
+        m_pos++;
+    }
+}
+
+FbTextElement::Sublist::operator bool() const
+{
+    return m_pos != m_list.end();
+}
+
+bool FbTextElement::Sublist::operator!() const
+{
+    return m_pos == m_list.end();
+}
+
+bool FbTextElement::Sublist::operator <(const QWebElement &element) const
+{
+    const QString name = element.attribute("class");
+    for (TypeList::const_iterator it = m_list.begin(); it != m_list.end(); it++) {
+        if (it->name() == name) return it < m_pos || element.isNull();
+    }
+    return false;
+}
+
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
 //  FbTextElement
 //  FbTextElement
 //---------------------------------------------------------------------------
 //---------------------------------------------------------------------------
@@ -69,6 +109,35 @@ void FbTextElement::getChildren(FbElementList &list)
     }
     }
 }
 }
 
 
+const FbTextElement::TypeList * FbTextElement::subtypes() const
+{
+    static Scheme scheme;
+    return scheme[tagName().toLower()];
+}
+
+FbTextElement::TypeList::const_iterator FbTextElement::subtype(const TypeList &list, const QString &style)
+{
+    for (TypeList::const_iterator item = list.begin(); item != list.end(); item++) {
+        if (item->name() == style) return item;
+    }
+    return list.end();
+}
+
+FbTextElement FbTextElement::insertInside(const QString &style, const QString &html)
+{
+    const TypeList * types = subtypes();
+    if (!types) return FbTextElement();
+
+    Sublist sublist(*types, style);
+    if (!sublist) return FbTextElement();
+
+    FbTextElement child = firstChild();
+    if (sublist < child) {
+        prependInside(html);
+        return firstChild();
+    }
+}
+
 QString FbTextElement::location()
 QString FbTextElement::location()
 {
 {
     static const QString javascript = FB2::read(":/js/get_location.js").prepend("var element=this;");
     static const QString javascript = FB2::read(":/js/get_location.js").prepend("var element=this;");

+ 26 - 9
source/fb2html.h

@@ -10,11 +10,9 @@ class FbTextElement;
 
 
 typedef QList<FbTextElement> FbElementList;
 typedef QList<FbTextElement> FbElementList;
 
 
-class FbTextScheme
+class FbTextElement : public QWebElement
 {
 {
-public:
-    explicit FbTextScheme();
-
+private:
     class Type
     class Type
     {
     {
     public:
     public:
@@ -33,16 +31,32 @@ public:
 
 
     typedef QMap<QString, TypeList> TypeMap;
     typedef QMap<QString, TypeList> TypeMap;
 
 
-private:
-    TypeMap m_types;
-};
+    class Scheme
+    {
+    public:
+        explicit Scheme();
+        const TypeList * operator[](const QString &name) const;
+    private:
+        TypeMap m_types;
+    };
+
+    class Sublist
+    {
+    public:
+        Sublist(const TypeList &list, const QString &name);
+        operator bool() const;
+        bool operator !() const;
+        bool operator <(const QWebElement &element) const;
+    private:
+        const TypeList &m_list;
+        TypeList::const_iterator m_pos;
+    };
 
 
-class FbTextElement : public QWebElement
-{
 public:
 public:
     FbTextElement() {}
     FbTextElement() {}
     FbTextElement(const QWebElement &x) : QWebElement(x) {}
     FbTextElement(const QWebElement &x) : QWebElement(x) {}
     FbTextElement &operator=(const QWebElement &x) { QWebElement::operator=(x); return *this; }
     FbTextElement &operator=(const QWebElement &x) { QWebElement::operator=(x); return *this; }
+    FbTextElement insertInside(const QString &style, const QString &html);
     void getChildren(FbElementList &list);
     void getChildren(FbElementList &list);
     QString location();
     QString location();
 
 
@@ -67,6 +81,9 @@ public:
 public:
 public:
     void select();
     void select();
 
 
+private:
+    const TypeList *subtypes() const;
+    TypeList::const_iterator subtype(const TypeList &list, const QString &style);
 };
 };
 
 
 class FbInsertCmd : public QUndoCommand
 class FbInsertCmd : public QUndoCommand