Quellcode durchsuchen

Simple QTextDocument object tree

Kandrashin Denis vor 13 Jahren
Ursprung
Commit
8afd25fb0f
6 geänderte Dateien mit 107 neuen und 13 gelöschten Zeilen
  1. 17 0
      source/fb2main.cpp
  2. 3 0
      source/fb2main.h
  3. 7 7
      source/fb2read.cpp
  4. 1 1
      source/fb2read.h
  5. 66 2
      source/fb2tree.cpp
  6. 13 3
      source/fb2tree.h

+ 17 - 0
source/fb2main.cpp

@@ -1,9 +1,11 @@
 #include <QtGui>
 #include <QtDebug>
+#include <QTreeView>
 
 #include "fb2main.h"
 #include "fb2doc.h"
 #include "fb2read.h"
+#include "fb2tree.h"
 
 #include <Qsci/qsciscintilla.h>
 #include <Qsci/qscilexerxml.h>
@@ -48,6 +50,7 @@ void MainWindow::init()
     textEdit = NULL;
     noteEdit = NULL;
     qsciEdit = NULL;
+    treeView = NULL;
     messageEdit = NULL;
 
     readSettings();
@@ -80,6 +83,11 @@ void MainWindow::logDestroyed()
     messageEdit = NULL;
 }
 
+void MainWindow::treeDestroyed()
+{
+    treeView = NULL;
+}
+
 bool MainWindow::loadXML(const QString &filename)
 {
     if (!filename.isEmpty()) {
@@ -147,6 +155,15 @@ void MainWindow::fileOpen()
 void MainWindow::sendDocument()
 {
     setCurrentFile(thread->file(), thread->doc());
+    treeView = new QTreeView(this);
+    treeView->setModel(new Fb2TreeModel(*textEdit));
+    treeView->setHeaderHidden(true);
+    connect(messageEdit, SIGNAL(destroyed()), SLOT(treeDestroyed()));
+    QDockWidget * dock = new QDockWidget(tr("Contents"), this);
+    dock->setAttribute(Qt::WA_DeleteOnClose);
+    dock->setFeatures(QDockWidget::AllDockWidgetFeatures);
+    dock->setWidget(treeView);
+    addDockWidget(Qt::LeftDockWidgetArea, dock);
 }
 
 bool MainWindow::fileSave()

+ 3 - 0
source/fb2main.h

@@ -10,6 +10,7 @@ class QMenu;
 class QFile;
 class QThread;
 class QTextEdit;
+class QTreeView;
 class QTextDocument;
 QT_END_NAMESPACE
 
@@ -41,6 +42,7 @@ private slots:
 
     void about();
     void documentWasModified();
+    void treeDestroyed();
     void logDestroyed();
     void logShowed();
     void viewQsci();
@@ -80,6 +82,7 @@ private:
     QTextEdit *noteEdit;
     QTextEdit *messageEdit;
     QsciScintilla *qsciEdit;
+    QTreeView * treeView;
     QString curFile;
     bool isUntitled;
 

+ 7 - 7
source/fb2read.cpp

@@ -142,10 +142,10 @@ FB2_END_KEYHASH
 Fb2Handler::RootHandler::RootHandler(QTextDocument &document, const QString &name)
     : BaseHandler(name)
     , m_document(document)
-    , m_cursor1(&document, false)
+    , m_cursor(&document, false)
     , m_empty(true)
 {
-    m_cursor1.beginEditBlock();
+    m_cursor.beginEditBlock();
 }
 
 Fb2Handler::RootHandler::~RootHandler()
@@ -154,17 +154,17 @@ Fb2Handler::RootHandler::~RootHandler()
     blockFormat.setTopMargin(6);
     blockFormat.setBottomMargin(6);
 
-    m_cursor1.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
-    m_cursor1.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
-    m_cursor1.mergeBlockFormat(blockFormat);
+    m_cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
+    m_cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+    m_cursor.mergeBlockFormat(blockFormat);
 
-    m_cursor1.endEditBlock();
+    m_cursor.endEditBlock();
 }
 
 Fb2Handler::BaseHandler * Fb2Handler::RootHandler::NewTag(const QString &name, const QXmlAttributes &attributes)
 {
     switch (toKeyword(name)) {
-        case Body   : { BaseHandler * handler = new BodyHandler(m_cursor1, name); m_empty = false; return handler; }
+        case Body   : { BaseHandler * handler = new BodyHandler(m_cursor, name); m_empty = false; return handler; }
         case Descr  : return new DescrHandler(name);
         case Binary : return new BinaryHandler(m_document, name, attributes);
         default: return NULL;

+ 1 - 1
source/fb2read.h

@@ -111,7 +111,7 @@ private:
         virtual BaseHandler * NewTag(const QString & name, const QXmlAttributes &attributes);
     private:
         QTextDocument &m_document;
-        Fb2TextCursor m_cursor1;
+        Fb2TextCursor m_cursor;
         bool m_empty;
     };
 

+ 66 - 2
source/fb2tree.cpp

@@ -1,11 +1,75 @@
 #include "fb2tree.h"
 
-Fb2TreeModel::Fb2TreeModel(QTextDocument &document, QObject *parent)
+#include <QTextDocument>
+#include <QTextDocumentFragment>
+#include <QTextFrame>
+
+Fb2TreeModel::Fb2TreeModel(QTextEdit &text, QObject *parent)
     : QAbstractItemModel(parent)
-    , m_document(document)
+    , m_text(text)
 {
 }
 
 Fb2TreeModel::~Fb2TreeModel()
 {
 }
+
+int Fb2TreeModel::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return 1;
+}
+
+QModelIndex Fb2TreeModel::index(int row, int column, const QModelIndex &parent) const
+{
+    void *data = parent.isValid() ? (void*)frame(parent) : NULL;
+    return createIndex(row, column, data);
+}
+
+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++;
+            }
+        }
+    }
+    return QModelIndex();
+}
+
+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;
+}
+
+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>");
+}

+ 13 - 3
source/fb2tree.h

@@ -2,18 +2,28 @@
 #define FB2TREE_H
 
 #include <QAbstractItemModel>
-#include <QTextDocument>
+#include <QTextEdit>
 
 class Fb2TreeModel: public QAbstractItemModel
 {
     Q_OBJECT
 
 public:
-    explicit Fb2TreeModel(QTextDocument &document, QObject *parent = 0);
+    explicit Fb2TreeModel(QTextEdit &text, QObject *parent = 0);
     virtual ~Fb2TreeModel();
 
+public:
+    virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+    virtual QModelIndex parent(const QModelIndex &child) const;
+    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+
+protected:
+    QTextFrame * frame(const QModelIndex &index) const;
+
 private:
-    QTextDocument & m_document;
+    QTextEdit & m_text;
 };
 
 #endif // FB2TREE_H