瀏覽代碼

Simple Fb2TreeModel for browse FB2

Kandrashin Denis 13 年之前
父節點
當前提交
3744e6ff0d
共有 2 個文件被更改,包括 95 次插入35 次删除
  1. 61 34
      source/fb2tree.cpp
  2. 34 1
      source/fb2tree.h

+ 61 - 34
source/fb2tree.cpp

@@ -1,17 +1,68 @@
 #include "fb2tree.h"
 
+#include <QtDebug>
 #include <QTextDocument>
 #include <QTextDocumentFragment>
 #include <QTextFrame>
 
+Fb2TreeItem::Fb2TreeItem(QTextFrame *frame, Fb2TreeItem *parent)
+    : QObject(parent)
+    , m_frame(frame)
+    , m_parent(parent)
+{
+    QTextCursor cursor(m_frame);
+    cursor.setPosition(m_frame->firstPosition(), QTextCursor::MoveAnchor);
+    cursor.setPosition(m_frame->lastPosition(), QTextCursor::KeepAnchor);
+    QTextDocumentFragment fragment(cursor);
+    m_text = fragment.toPlainText().simplified().left(255);
+    foreach (QTextFrame * frame, frame->childFrames()) {
+        m_list << new Fb2TreeItem(frame, this);
+    }
+}
+
+Fb2TreeItem::~Fb2TreeItem()
+{
+    foreach (Fb2TreeItem * item, m_list) {
+        delete item;
+    }
+}
+
+Fb2TreeItem * Fb2TreeItem::item(int index) const
+{
+    if (index < 0 || index >= m_list.size()) return NULL;
+    return m_list[index];
+}
+
+QString Fb2TreeItem::text() const
+{
+    return tr("<section>") + m_text;
+}
+
+//---------------------------------------------------------------------------
+//  Fb2TreeModel
+//---------------------------------------------------------------------------
+
 Fb2TreeModel::Fb2TreeModel(QTextEdit &text, QObject *parent)
     : QAbstractItemModel(parent)
     , m_text(text)
+    , m_root(NULL)
 {
+    if (QTextDocument * doc = text.document()) {
+        m_root = new Fb2TreeItem(doc->rootFrame());
+    }
 }
 
 Fb2TreeModel::~Fb2TreeModel()
 {
+    if (m_root) delete m_root;
+}
+
+Fb2TreeItem * Fb2TreeModel::item(const QModelIndex &index) const
+{
+    if (!m_root) return NULL;
+    if (!index.isValid()) return m_root;
+    Fb2TreeItem * parent = item(index.parent());
+    return parent ? parent->item(index.row()) : NULL;
 }
 
 int Fb2TreeModel::columnCount(const QModelIndex &parent) const
@@ -22,18 +73,16 @@ int Fb2TreeModel::columnCount(const QModelIndex &parent) const
 
 QModelIndex Fb2TreeModel::index(int row, int column, const QModelIndex &parent) const
 {
-    void *data = parent.isValid() ? (void*)frame(parent) : NULL;
-    return createIndex(row, column, data);
+    if (!m_root) return QModelIndex();
+    Fb2TreeItem * i  = item(parent);
+    return i ? createIndex(row, column, (void*)i) : QModelIndex();
 }
 
 QModelIndex Fb2TreeModel::parent(const QModelIndex &child) const
 {
-    if (QTextFrame * frame  = static_cast<QTextFrame*>(child.internalPointer())) {
-        if (QTextFrame * parent = frame->parentFrame()) {
-            int row = 0;
-            foreach (QTextFrame * f, parent->childFrames()) {
-                if (f == frame) return createIndex(row, 0, (void*)parent); else row++;
-            }
+    if (Fb2TreeItem * parent = static_cast<Fb2TreeItem*>(child.internalPointer())) {
+        if (Fb2TreeItem * owner = parent->parent()) {
+            return createIndex(owner->index(parent), 0, (void*)owner);
         }
     }
     return QModelIndex();
@@ -41,35 +90,13 @@ QModelIndex Fb2TreeModel::parent(const QModelIndex &child) const
 
 int Fb2TreeModel::rowCount(const QModelIndex &parent) const
 {
-    QTextFrame * f = frame(parent);
-    return f ? f->childFrames().count() : 0;
-}
-
-QTextFrame * Fb2TreeModel::frame(const QModelIndex &index) const
-{
-    if (!index.isValid()) {
-        QTextDocument * doc = m_text.document();
-        return doc ? doc->rootFrame() : NULL;
-    }
-    if (QTextFrame * parent = frame(index.parent())) {
-        int i = index.row();
-        foreach (QTextFrame * frame, parent->childFrames()) {
-            if (i == 0) return frame; else i--;
-        }
-    }
-    return NULL;
+    Fb2TreeItem * i  = item(parent);
+    return i ? i->count() : 0;
 }
 
 QVariant Fb2TreeModel::data(const QModelIndex &index, int role) const
 {
     if (role != Qt::DisplayRole) return QVariant();
-    if (QTextFrame * f = frame(index)) {
-        QTextCursor cursor(f);
-        cursor.setPosition(f->firstPosition(), QTextCursor::MoveAnchor);
-        cursor.setPosition(f->lastPosition(), QTextCursor::KeepAnchor);
-        QTextDocumentFragment fragment(cursor);
-        QString text = fragment.toPlainText();
-        return text.simplified();
-    }
-    return tr("<section>");
+    Fb2TreeItem * i  = item(index);
+    return i ? i->text() : QVariant();
 }

+ 34 - 1
source/fb2tree.h

@@ -4,6 +4,38 @@
 #include <QAbstractItemModel>
 #include <QTextEdit>
 
+class Fb2TreeItem: public QObject
+{
+    Q_OBJECT
+
+public:
+    explicit Fb2TreeItem(QTextFrame *frame, Fb2TreeItem *parent = 0);
+
+    virtual ~Fb2TreeItem();
+
+    Fb2TreeItem * item(int index) const;
+
+    int index(Fb2TreeItem * child) const {
+        return m_list.indexOf(child);
+    }
+
+    int count() const {
+        return m_list.size();
+    }
+
+    Fb2TreeItem * parent() const {
+        return m_parent;
+    }
+
+    QString text() const;
+
+private:
+    QList<Fb2TreeItem*> m_list;
+    QString m_text;
+    QTextFrame * m_frame;
+    Fb2TreeItem * m_parent;
+};
+
 class Fb2TreeModel: public QAbstractItemModel
 {
     Q_OBJECT
@@ -20,10 +52,11 @@ public:
     virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
 
 protected:
-    QTextFrame * frame(const QModelIndex &index) const;
+    Fb2TreeItem * item(const QModelIndex &index) const;
 
 private:
     QTextEdit & m_text;
+    Fb2TreeItem * m_root;
 };
 
 #endif // FB2TREE_H