Răsfoiți Sursa

View footnotes

Kandrashin Denis 12 ani în urmă
părinte
comite
1d9e3a16cb

+ 4 - 0
fb2edit.pro

@@ -8,7 +8,9 @@ HEADERS = \
     source/fb2dock.hpp \
     source/fb2head.hpp \
     source/fb2imgs.hpp \
+    source/fb2list.hpp \
     source/fb2main.hpp \
+    source/fb2note.hpp \
     source/fb2page.hpp \
     source/fb2read.hpp \
     source/fb2tree.hpp \
@@ -25,7 +27,9 @@ SOURCES = \
     source/fb2head.cpp \
     source/fb2html.cpp \
     source/fb2imgs.cpp \
+    source/fb2list.cpp \
     source/fb2main.cpp \
+    source/fb2note.cpp \
     source/fb2page.cpp \
     source/fb2read.cpp \
     source/fb2save.cpp \

+ 0 - 74
source/fb2dlgs.cpp

@@ -82,80 +82,6 @@ void FbTextFindDlg::find()
     m_edit.findText(text, options);
 }
 
-//---------------------------------------------------------------------------
-//  FbNoteDlg
-//---------------------------------------------------------------------------
-
-FbNoteDlg::FbNoteDlg(FbTextEdit &view)
-    : QDialog(&view)
-{
-    setWindowTitle(tr("Insert footnote"));
-    resize(460, 300);
-
-    QGridLayout * gridLayout = new QGridLayout(this);
-
-    QLabel * label1 = new QLabel(this);
-    label1->setText(tr("Identifier:"));
-    gridLayout->addWidget(label1, 0, 0, 1, 1);
-
-    m_key = new QComboBox(this);
-    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
-    gridLayout->addWidget(m_key, 0, 1, 1, 1);
-
-    QLabel * label2 = new QLabel(this);
-    label2->setText(tr("Title:"));
-    gridLayout->addWidget(label2, 1, 0, 1, 1);
-
-    m_title = new QLineEdit(this);
-    m_title->setObjectName(QString::fromUtf8("m_title"));
-    gridLayout->addWidget(m_title, 1, 1, 1, 1);
-
-    m_toolbar = new QToolBar(this);
-    gridLayout->addWidget(m_toolbar, 2, 0, 1, 2);
-
-    QFrame * frame = new QFrame(this);
-    frame->setFrameShape(QFrame::StyledPanel);
-    frame->setFrameShadow(QFrame::Sunken);
-    gridLayout->addWidget(frame, 3, 0, 1, 2);
-
-    QLayout * frameLayout = new QHBoxLayout(frame);
-    frameLayout->setSpacing(0);
-    frameLayout->setMargin(0);
-
-    m_text = new FbTextBase(frame);
-    m_text->setObjectName(QString::fromUtf8("m_text"));
-    m_text->setUrl(QUrl(QString::fromUtf8("about:blank")));
-    frameLayout->addWidget(m_text);
-
-    QDialogButtonBox * buttonBox = new QDialogButtonBox(this);
-    buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
-    buttonBox->setOrientation(Qt::Horizontal);
-    buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
-    gridLayout->addWidget(buttonBox, 4, 0, 1, 2);
-
-    QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
-    QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
-
-    m_key->addItem(tr("<create new>"));
-    m_key->setCurrentIndex(0);
-    m_title->setFocus();
-
-    FbTextPage *page = new FbTextPage(this);
-    connect(m_text, SIGNAL(loadFinished(bool)), SLOT(loadFinished()));
-    page->setNetworkAccessManager(view.page()->networkAccessManager());
-    page->setContentEditable(true);
-    m_text->setPage(page);
-    m_text->setHtml("<body><p><br></p></body>");
-
-    m_text->addTools(m_toolbar);
-}
-
-void FbNoteDlg::loadFinished()
-{
-    FbTextElement body = m_text->page()->mainFrame()->documentElement().findFirst("body");
-    body.select();
-}
-
 //---------------------------------------------------------------------------
 //  FbSetupDlg
 //---------------------------------------------------------------------------

+ 0 - 17
source/fb2dlgs.hpp

@@ -54,23 +54,6 @@ private:
     FbTextEdit & m_edit;
 };
 
-class FbNoteDlg : public QDialog
-{
-    Q_OBJECT
-    
-public:
-    explicit FbNoteDlg(FbTextEdit &view);
-
-private slots:
-    void loadFinished();
-
-private:
-    QComboBox *m_key;
-    FbTextBase *m_text;
-    QLineEdit *m_title;
-    QToolBar *m_toolbar;
-};
-
 class FbSetupDlg : public QDialog
 {
     Q_OBJECT

+ 9 - 43
source/fb2imgs.cpp

@@ -9,12 +9,14 @@
 #include <QImageReader>
 #include <QLabel>
 #include <QLineEdit>
+#include <QSplitter>
 #include <QUrl>
 #include <QVBoxLayout>
 #include <QWebFrame>
 #include <QTabWidget>
 #include <QtDebug>
 
+#include "fb2list.hpp"
 #include "fb2page.hpp"
 #include "fb2text.hpp"
 #include "fb2utils.h"
@@ -442,8 +444,8 @@ QString FbImageDlg::result() const
 
 FbImgsModel::FbImgsModel(FbTextEdit *text, QObject *parent)
     : QAbstractListModel(parent)
-    , m_text(text)
 {
+    manager = qobject_cast<FbNetworkAccessManager*>(text->page()->networkAccessManager());
 }
 
 int FbImgsModel::columnCount(const QModelIndex &parent) const
@@ -454,9 +456,7 @@ int FbImgsModel::columnCount(const QModelIndex &parent) const
 
 int FbImgsModel::rowCount(const QModelIndex &parent) const
 {
-    Q_UNUSED(parent);
-    FbNetworkAccessManager * f = files();
-    return f ? f->count() : 0;
+    return parent.isValid() ? 0 : manager->count();
 }
 
 QVariant FbImgsModel::headerData(int section, Qt::Orientation orientation, int role) const
@@ -471,22 +471,12 @@ QVariant FbImgsModel::headerData(int section, Qt::Orientation orientation, int r
     return QVariant();
 }
 
-FbNetworkAccessManager * FbImgsModel::files() const
-{
-    if (FbTextPage *page = qobject_cast<FbTextPage*>(m_text->page())) {
-        return qobject_cast<FbNetworkAccessManager*>(page->networkAccessManager());
-    } else {
-        return 0;
-    }
-}
-
 QVariant FbImgsModel::data(const QModelIndex &index, int role) const
 {
     if (index.isValid()) {
         switch (role) {
             case Qt::DisplayRole: {
-                FbNetworkAccessManager * f = files();
-                return f ? f->info(index.row(), index.column()) : QVariant();
+                return manager->info(index.row(), index.column());
             } break;
             case Qt::TextAlignmentRole: {
                 switch (index.column()) {
@@ -499,31 +489,6 @@ QVariant FbImgsModel::data(const QModelIndex &index, int role) const
     return QVariant();
 }
 
-//---------------------------------------------------------------------------
-//  FbImgsView
-//---------------------------------------------------------------------------
-
-#include <QSplitter>
-#include <QScrollArea>
-
-FbImgsView::FbImgsView(QWidget *parent)
-    : QTreeView(parent)
-{
-    setAllColumnsShowFocus(true);
-}
-
-void FbImgsView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
-{
-    QTreeView::currentChanged(current, previous);
-    QModelIndex index = model()->index(current.row(), 0);
-    emit showImage(model()->data(index).toString());
-}
-
-FbImgsModel * FbImgsView::model() const
-{
-    return qobject_cast<FbImgsModel*>(QTreeView::model());
-}
-
 //---------------------------------------------------------------------------
 //  FbImgsWidget
 //---------------------------------------------------------------------------
@@ -538,7 +503,7 @@ FbImgsWidget::FbImgsWidget(FbTextEdit *text, QWidget* parent)
 
     QSplitter *splitter = new QSplitter(Qt::Vertical, this);
 
-    m_list = new FbImgsView(splitter);
+    m_list = new FbListView(splitter);
     splitter->addWidget(m_list);
 
     FbTextFrame *frame = new FbTextFrame(splitter);
@@ -553,12 +518,13 @@ FbImgsWidget::FbImgsWidget(FbTextEdit *text, QWidget* parent)
     layout->addWidget(splitter);
 
     connect(m_text, SIGNAL(loadFinished(bool)), SLOT(loadFinished()));
-    connect(m_list, SIGNAL(showImage(QString)), SLOT(showImage(QString)));
+    connect(m_list, SIGNAL(showCurrent(QString)), SLOT(showCurrent(QString)));
     loadFinished();
 }
 
 void FbImgsWidget::loadFinished()
 {
+    if (QAbstractItemModel *m = m_list->model()) m->deleteLater();
     m_view->load(QUrl());
     m_list->setModel(new FbImgsModel(m_text, this));
     m_list->reset();
@@ -568,7 +534,7 @@ void FbImgsWidget::loadFinished()
     m_list->setColumnHidden(0, true);
 }
 
-void FbImgsWidget::showImage(const QString &name)
+void FbImgsWidget::showCurrent(const QString &name)
 {
     QUrl url = m_text->url();
     url.setFragment(name);

+ 3 - 21
source/fb2imgs.hpp

@@ -184,25 +184,7 @@ public:
     QVariant headerData(int section, Qt::Orientation orientation, int role) const;
 
 private:
-    FbNetworkAccessManager *files() const;
-
-private:
-    FbTextEdit *m_text;
-};
-
-class FbImgsView : public QTreeView
-{
-    Q_OBJECT
-
-public:
-    explicit FbImgsView(QWidget *parent = 0);
-    FbImgsModel *model() const;
-
-protected:
-    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
-
-signals:
-    void showImage(const QString &name);
+    FbNetworkAccessManager *manager;
 };
 
 class FbImgsWidget : public QWidget
@@ -214,14 +196,14 @@ public:
     QSize sizeHint() const { return QSize(200,200); }
 
 public slots:
-    void showImage(const QString &name);
+    void showCurrent(const QString &name);
 
 private slots:
     void loadFinished();
 
 private:
     FbTextEdit *m_text;
-    FbImgsView *m_list;
+    QTreeView *m_list;
     QWebView *m_view;
 };
 

+ 19 - 0
source/fb2list.cpp

@@ -0,0 +1,19 @@
+#include "fb2list.hpp"
+
+//---------------------------------------------------------------------------
+//  FbListView
+//---------------------------------------------------------------------------
+
+FbListView::FbListView(QWidget *parent)
+    : QTreeView(parent)
+{
+    setAllColumnsShowFocus(true);
+}
+
+void FbListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+    QTreeView::currentChanged(current, previous);
+    QModelIndex index = model()->index(current.row(), 0);
+    emit showCurrent(model()->data(index).toString());
+}
+

+ 20 - 0
source/fb2list.hpp

@@ -0,0 +1,20 @@
+#ifndef FB2LIST_H
+#define FB2LIST_H
+
+#include <QTreeView>
+
+class FbListView : public QTreeView
+{
+    Q_OBJECT
+
+public:
+    explicit FbListView(QWidget *parent = 0);
+
+protected:
+    void currentChanged(const QModelIndex &current, const QModelIndex &previous);
+
+signals:
+    void showCurrent(const QString &name);
+};
+
+#endif // FB2LIST_H

+ 5 - 0
source/fb2main.cpp

@@ -470,6 +470,11 @@ void FbMainWindow::createActions()
     act->setCheckable(true);
     menu->addAction(act);
 
+    act = new QAction(tr("&Footnotes"), this);
+    text->setAction(Fb::ViewFootnotes, act);
+    act->setCheckable(true);
+    menu->addAction(act);
+
     act = new QAction(tr("&Web inspector"), this);
     text->setAction(Fb::ViewInspector, act);
     act->setCheckable(true);

+ 1 - 0
source/fb2mode.h

@@ -54,6 +54,7 @@ enum Actions {
     SectionDel,
     ViewContents,
     ViewPictures,
+    ViewFootnotes,
     ViewInspector,
     ZoomIn,
     ZoomOut,

+ 203 - 0
source/fb2note.cpp

@@ -0,0 +1,203 @@
+#include "fb2note.hpp"
+
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <QHeaderView>
+#include <QLabel>
+#include <QLineEdit>
+#include <QSplitter>
+#include <QToolBar>
+#include <QWebFrame>
+#include <QWebPage>
+#include <QWebView>
+
+#include "fb2list.hpp"
+#include "fb2page.hpp"
+#include "fb2text.hpp"
+#include "fb2html.h"
+
+//---------------------------------------------------------------------------
+//  FbNoteDlg
+//---------------------------------------------------------------------------
+
+FbNoteDlg::FbNoteDlg(FbTextBase *text)
+    : QDialog(text)
+{
+    setWindowTitle(tr("Insert footnote"));
+    resize(460, 300);
+
+    QGridLayout * gridLayout = new QGridLayout(this);
+
+    QLabel * label1 = new QLabel(this);
+    label1->setText(tr("Identifier:"));
+    gridLayout->addWidget(label1, 0, 0, 1, 1);
+
+    m_key = new QComboBox(this);
+    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+    gridLayout->addWidget(m_key, 0, 1, 1, 1);
+
+    QLabel * label2 = new QLabel(this);
+    label2->setText(tr("Title:"));
+    gridLayout->addWidget(label2, 1, 0, 1, 1);
+
+    m_title = new QLineEdit(this);
+    m_title->setObjectName(QString::fromUtf8("m_title"));
+    gridLayout->addWidget(m_title, 1, 1, 1, 1);
+
+    m_toolbar = new QToolBar(this);
+    gridLayout->addWidget(m_toolbar, 2, 0, 1, 2);
+
+    QFrame * frame = new QFrame(this);
+    frame->setFrameShape(QFrame::StyledPanel);
+    frame->setFrameShadow(QFrame::Sunken);
+    gridLayout->addWidget(frame, 3, 0, 1, 2);
+
+    QLayout * frameLayout = new QHBoxLayout(frame);
+    frameLayout->setSpacing(0);
+    frameLayout->setMargin(0);
+
+    m_text = new FbTextBase(frame);
+    m_text->setObjectName(QString::fromUtf8("m_text"));
+    m_text->setUrl(QUrl(QString::fromUtf8("about:blank")));
+    frameLayout->addWidget(m_text);
+
+    QDialogButtonBox * buttonBox = new QDialogButtonBox(this);
+    buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
+    buttonBox->setOrientation(Qt::Horizontal);
+    buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
+    gridLayout->addWidget(buttonBox, 4, 0, 1, 2);
+
+    QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+    QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
+
+    m_key->addItem(tr("<create new>"));
+    m_key->setCurrentIndex(0);
+    m_title->setFocus();
+
+    FbTextPage *page = new FbTextPage(this);
+    connect(m_text, SIGNAL(loadFinished(bool)), SLOT(loadFinished()));
+    page->setNetworkAccessManager(text->page()->networkAccessManager());
+    page->setContentEditable(true);
+    m_text->setPage(page);
+    m_text->setHtml("<body><p><br></p></body>");
+
+    m_text->addTools(m_toolbar);
+}
+
+void FbNoteDlg::loadFinished()
+{
+    FbTextElement body = m_text->page()->mainFrame()->documentElement().findFirst("body");
+    body.select();
+}
+
+//---------------------------------------------------------------------------
+//  FbNotesModel
+//---------------------------------------------------------------------------
+
+FbNotesModel::FbNotesModel(FbTextPage *page, QObject *parent)
+    : QAbstractListModel(parent)
+    , collection(page->body().findAll("a"))
+    , m_page(page)
+{
+}
+
+int FbNotesModel::columnCount(const QModelIndex &parent) const
+{
+    Q_UNUSED(parent);
+    return 4;
+}
+
+int FbNotesModel::rowCount(const QModelIndex &parent) const
+{
+    return parent.isValid() ? 0 : collection.count();
+}
+
+QVariant FbNotesModel::headerData(int section, Qt::Orientation orientation, int role) const
+{
+    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+        switch (section) {
+            case 1: return tr("Title");
+            case 2: return tr("Type");
+            case 3: return tr("Link");
+        }
+    }
+    return QVariant();
+}
+
+QVariant FbNotesModel::data(const QModelIndex &index, int role) const
+{
+    if (index.isValid()) {
+        switch (role) {
+            case Qt::DisplayRole: {
+                int row = index.row();
+                if (row < 0 || row >= collection.count()) return QVariant();
+                QWebElement element = collection[row];
+                switch (index.column()) {
+                    case 1: return element.toPlainText();
+                    case 2: return element.attribute("type");
+                    default: return element.attribute("href");
+                }
+            } break;
+            case Qt::TextAlignmentRole: {
+                return Qt::AlignLeft;
+            }
+        }
+    }
+    return QVariant();
+}
+
+//---------------------------------------------------------------------------
+//  FbNotesWidget
+//---------------------------------------------------------------------------
+
+FbNotesWidget::FbNotesWidget(FbTextEdit *text, QWidget* parent)
+    : QWidget(parent)
+    , m_text(text)
+{
+    QVBoxLayout *layout = new QVBoxLayout(this);
+    layout->setSpacing(0);
+    layout->setContentsMargins(0, 0, 0, 0);
+
+    QSplitter *splitter = new QSplitter(Qt::Vertical, this);
+
+    m_list = new FbListView(splitter);
+    m_list->header()->setDefaultSectionSize(50);
+    splitter->addWidget(m_list);
+
+    FbTextFrame *frame = new FbTextFrame(splitter);
+    splitter->addWidget(frame);
+
+    m_view = new FbTextBase(frame);
+    m_view->page()->setNetworkAccessManager(text->page()->networkAccessManager());
+    m_view->page()->settings()->setUserStyleSheetUrl(QUrl::fromLocalFile(":style.css"));
+    frame->layout()->addWidget(m_view);
+
+    splitter->setSizes(QList<int>() << 100 << 100);
+
+    layout->addWidget(splitter);
+
+    connect(m_text, SIGNAL(loadFinished(bool)), SLOT(loadFinished()));
+    connect(m_list, SIGNAL(showCurrent(QString)), SLOT(showCurrent(QString)));
+    loadFinished();
+}
+
+void FbNotesWidget::loadFinished()
+{
+    if (QAbstractItemModel *m = m_list->model()) m->deleteLater();
+    m_view->load(QUrl());
+    m_list->setModel(new FbNotesModel(m_text->page(), this));
+    m_list->reset();
+    m_list->setColumnHidden(0, true);
+}
+
+void FbNotesWidget::showCurrent(const QString &name)
+{
+    QWebElement element = m_text->body().findFirst(name);
+    QString html = element.toInnerXml();
+    html.prepend(
+        "<fb:body name=notes style='padding:0;margin:0;'>"
+        "<fb:section id=0 style='border:0;padding:0;margin:0;'>"
+    );
+    html.append("</fb:section></fb:body>");
+    m_view->setHtml(html, m_view->url());
+}

+ 77 - 0
source/fb2note.hpp

@@ -0,0 +1,77 @@
+#ifndef FB2NOTE_H
+#define FB2NOTE_H
+
+#include <QAbstractListModel>
+#include <QDialog>
+#include <QList>
+#include <QTreeView>
+#include <QWebElement>
+#include <QWebElementCollection>
+
+QT_BEGIN_NAMESPACE
+class QComboBox;
+class QLineEdit;
+class QToolBar;
+class QWebView;
+QT_END_NAMESPACE
+
+class FbTextPage;
+class FbTextBase;
+class FbTextEdit;
+
+class FbNoteDlg : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit FbNoteDlg(FbTextBase *text);
+
+private slots:
+    void loadFinished();
+
+private:
+    QComboBox *m_key;
+    FbTextBase *m_text;
+    QLineEdit *m_title;
+    QToolBar *m_toolbar;
+};
+
+class FbNotesModel : public QAbstractListModel
+{
+    Q_OBJECT
+
+public:
+    explicit FbNotesModel(FbTextPage *page, QObject *parent = 0);
+
+public:
+    int rowCount(const QModelIndex &parent = QModelIndex()) const;
+    int columnCount(const QModelIndex &parent = QModelIndex()) const;
+    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+private:
+    QWebElementCollection collection;
+    FbTextPage *m_page;
+};
+
+class FbNotesWidget : public QWidget
+{
+    Q_OBJECT
+
+public:
+    explicit FbNotesWidget(FbTextEdit *text, QWidget* parent = 0);
+    QSize sizeHint() const { return QSize(200,200); }
+
+public slots:
+    void showCurrent(const QString &name);
+
+private slots:
+    void loadFinished();
+
+private:
+    FbTextEdit *m_text;
+    QTreeView *m_list;
+    QWebView *m_view;
+};
+
+#endif // FB2NOTE_H

+ 25 - 1
source/fb2text.cpp

@@ -13,6 +13,7 @@
 #include <QtDebug>
 
 #include "fb2dlgs.hpp"
+#include "fb2note.hpp"
 #include "fb2page.hpp"
 #include "fb2save.hpp"
 #include "fb2tree.hpp"
@@ -212,6 +213,7 @@ FbTextEdit::FbTextEdit(QWidget *parent, QObject *owner)
     , m_noteView(0)
     , m_thread(0)
     , dockTree(0)
+    , dockNote(0)
     , dockImgs(0)
     , dockInsp(0)
 {
@@ -270,6 +272,7 @@ void FbTextEdit::connectActions(QToolBar *tool)
 
     connect(act(Fb::ViewContents), SIGNAL(triggered(bool)), SLOT(viewContents(bool)));
     connect(act(Fb::ViewPictures), SIGNAL(triggered(bool)), SLOT(viewPictures(bool)));
+    connect(act(Fb::ViewFootnotes), SIGNAL(triggered(bool)), SLOT(viewFootnotes(bool)));
     connect(act(Fb::ViewInspector), SIGNAL(triggered(bool)), SLOT(viewInspector(bool)));
 
     connect(act(Fb::ZoomIn), SIGNAL(triggered()), SLOT(zoomIn()));
@@ -366,6 +369,21 @@ void FbTextEdit::viewPictures(bool show)
     }
 }
 
+void FbTextEdit::viewFootnotes(bool show)
+{
+    if (show) {
+        if (dockNote) { dockNote->show(); return; }
+        dockNote = new FbDockWidget(tr("Footnotes"), this);
+        dockNote->setWidget(new FbNotesWidget(this, m_owner));
+        connect(dockNote, SIGNAL(visibilityChanged(bool)), act(Fb::ViewFootnotes), SLOT(setChecked(bool)));
+        connect(dockNote, SIGNAL(destroyed()), SLOT(noteDestroyed()));
+        m_owner->addDockWidget(Qt::RightDockWidgetArea, dockNote);
+    } else if (dockNote) {
+        dockNote->deleteLater();
+        dockNote = 0;
+    }
+}
+
 void FbTextEdit::viewInspector(bool show)
 {
     if (show) {
@@ -410,6 +428,12 @@ void FbTextEdit::imgsDestroyed()
     dockImgs = 0;
 }
 
+void FbTextEdit::noteDestroyed()
+{
+    m_actions[Fb::ViewFootnotes]->setChecked(false);
+    dockNote = 0;
+}
+
 FbNoteView & FbTextEdit::noteView()
 {
     if (m_noteView) return *m_noteView;
@@ -593,7 +617,7 @@ void FbTextEdit::insertImage()
 
 void FbTextEdit::insertNote()
 {
-    FbNoteDlg dlg(*this);
+    FbNoteDlg dlg(this);
     dlg.exec();
 }
 

+ 6 - 2
source/fb2text.hpp

@@ -94,12 +94,16 @@ public:
     bool SubChecked();
     bool SupChecked();
 
+    QWebElement body();
+    QWebElement doc();
+
 protected:
     virtual void mouseMoveEvent(QMouseEvent *event);
 
 public slots:
     void viewContents(bool show);
     void viewPictures(bool show);
+    void viewFootnotes(bool show);
     void viewInspector(bool show);
     void insertImage();
     void insertNote();
@@ -111,6 +115,7 @@ private slots:
     void contextMenu(const QPoint &pos);
     void treeDestroyed();
     void imgsDestroyed();
+    void noteDestroyed();
     void zoomIn();
     void zoomOut();
     void zoomReset();
@@ -121,8 +126,6 @@ private:
     void execCommand(const QString &cmd, const QString &arg);
     FbBinary * file(const QString &name);
     FbNoteView & noteView();
-    QWebElement body();
-    QWebElement doc();
 
 private:
     QMainWindow *m_owner;
@@ -130,6 +133,7 @@ private:
     FbReadThread *m_thread;
     FbActionMap m_actions;
     QDockWidget *dockTree;
+    QDockWidget *dockNote;
     QDockWidget *dockImgs;
     QDockWidget *dockInsp;
     QPoint m_point;