fb2note.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include "fb2note.hpp"
  2. #include <QComboBox>
  3. #include <QDialogButtonBox>
  4. #include <QHeaderView>
  5. #include <QLabel>
  6. #include <QLineEdit>
  7. #include <QSplitter>
  8. #include <QToolBar>
  9. #include <QWebFrame>
  10. #include <QWebPage>
  11. #include <QWebView>
  12. #include "fb2list.hpp"
  13. #include "fb2page.hpp"
  14. #include "fb2text.hpp"
  15. #include "fb2html.h"
  16. //---------------------------------------------------------------------------
  17. // FbNoteDlg
  18. //---------------------------------------------------------------------------
  19. FbNoteDlg::FbNoteDlg(FbTextBase *text)
  20. : QDialog(text)
  21. {
  22. setWindowTitle(tr("Insert footnote"));
  23. resize(460, 300);
  24. QGridLayout * gridLayout = new QGridLayout(this);
  25. QLabel * label1 = new QLabel(this);
  26. label1->setText(tr("Identifier:"));
  27. gridLayout->addWidget(label1, 0, 0, 1, 1);
  28. m_key = new QComboBox(this);
  29. QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  30. gridLayout->addWidget(m_key, 0, 1, 1, 1);
  31. QLabel * label2 = new QLabel(this);
  32. label2->setText(tr("Title:"));
  33. gridLayout->addWidget(label2, 1, 0, 1, 1);
  34. m_title = new QLineEdit(this);
  35. m_title->setObjectName(QString::fromUtf8("m_title"));
  36. gridLayout->addWidget(m_title, 1, 1, 1, 1);
  37. m_toolbar = new QToolBar(this);
  38. m_toolbar->setIconSize(QSize(24, 24));
  39. gridLayout->addWidget(m_toolbar, 2, 0, 1, 2);
  40. QFrame * frame = new QFrame(this);
  41. frame->setFrameShape(QFrame::StyledPanel);
  42. frame->setFrameShadow(QFrame::Sunken);
  43. gridLayout->addWidget(frame, 3, 0, 1, 2);
  44. QLayout * frameLayout = new QHBoxLayout(frame);
  45. frameLayout->setSpacing(0);
  46. frameLayout->setMargin(0);
  47. m_text = new FbTextBase(frame);
  48. m_text->setObjectName(QString::fromUtf8("m_text"));
  49. m_text->setUrl(QUrl(QString::fromUtf8("about:blank")));
  50. frameLayout->addWidget(m_text);
  51. QDialogButtonBox * buttonBox = new QDialogButtonBox(this);
  52. buttonBox->setObjectName(QString::fromUtf8("buttonBox"));
  53. buttonBox->setOrientation(Qt::Horizontal);
  54. buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
  55. gridLayout->addWidget(buttonBox, 4, 0, 1, 2);
  56. QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
  57. QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
  58. m_key->addItem(tr("<create new>"));
  59. m_key->setCurrentIndex(0);
  60. m_title->setFocus();
  61. FbTextPage *page = new FbTextPage(this);
  62. connect(m_text, SIGNAL(loadFinished(bool)), SLOT(loadFinished()));
  63. page->setNetworkAccessManager(text->page()->networkAccessManager());
  64. page->setContentEditable(true);
  65. m_text->setPage(page);
  66. m_text->setHtml("<body><p><br></p></body>");
  67. m_text->addTools(m_toolbar);
  68. }
  69. void FbNoteDlg::loadFinished()
  70. {
  71. FbTextElement body = m_text->page()->mainFrame()->documentElement().findFirst("body");
  72. body.select();
  73. }
  74. //---------------------------------------------------------------------------
  75. // FbNotesModel
  76. //---------------------------------------------------------------------------
  77. FbNotesModel::FbNotesModel(FbTextPage *page, QObject *parent)
  78. : QAbstractListModel(parent)
  79. , collection(page->body().findAll("a"))
  80. , m_page(page)
  81. {
  82. }
  83. FbTextElement FbNotesModel::at(const QModelIndex &index) const
  84. {
  85. int row = index.row();
  86. if (row < 0 || row >= collection.count()) return QWebElement();
  87. return collection.at(row);
  88. }
  89. int FbNotesModel::columnCount(const QModelIndex &parent) const
  90. {
  91. Q_UNUSED(parent);
  92. return 4;
  93. }
  94. int FbNotesModel::rowCount(const QModelIndex &parent) const
  95. {
  96. return parent.isValid() ? 0 : collection.count();
  97. }
  98. QVariant FbNotesModel::headerData(int section, Qt::Orientation orientation, int role) const
  99. {
  100. if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
  101. switch (section) {
  102. case 1: return tr("Title");
  103. case 2: return tr("Type");
  104. case 3: return tr("Link");
  105. }
  106. }
  107. return QVariant();
  108. }
  109. QVariant FbNotesModel::data(const QModelIndex &index, int role) const
  110. {
  111. if (index.isValid()) {
  112. switch (role) {
  113. case Qt::DisplayRole: {
  114. QWebElement element = at(index);
  115. switch (index.column()) {
  116. case 1: return element.toPlainText();
  117. case 2: return element.attribute("type");
  118. default: return element.attribute("href");
  119. }
  120. } break;
  121. case Qt::TextAlignmentRole: {
  122. return Qt::AlignLeft;
  123. }
  124. }
  125. }
  126. return QVariant();
  127. }
  128. //---------------------------------------------------------------------------
  129. // FbNotesWidget
  130. //---------------------------------------------------------------------------
  131. FbNotesWidget::FbNotesWidget(FbTextEdit *text, QWidget* parent)
  132. : QWidget(parent)
  133. , m_text(text)
  134. {
  135. QVBoxLayout *layout = new QVBoxLayout(this);
  136. layout->setSpacing(0);
  137. layout->setContentsMargins(0, 0, 0, 0);
  138. QSplitter *splitter = new QSplitter(Qt::Vertical, this);
  139. m_list = new FbListView(splitter);
  140. m_list->header()->setDefaultSectionSize(50);
  141. splitter->addWidget(m_list);
  142. FbTextFrame *frame = new FbTextFrame(splitter);
  143. splitter->addWidget(frame);
  144. m_view = new FbTextBase(frame);
  145. m_view->page()->setNetworkAccessManager(text->page()->networkAccessManager());
  146. m_view->page()->settings()->setUserStyleSheetUrl(QUrl::fromLocalFile(":style.css"));
  147. frame->layout()->addWidget(m_view);
  148. splitter->setSizes(QList<int>() << 100 << 100);
  149. layout->addWidget(splitter);
  150. connect(m_text, SIGNAL(loadFinished(bool)), SLOT(loadFinished()));
  151. connect(m_list, SIGNAL(showCurrent(QString)), SLOT(showCurrent(QString)));
  152. connect(m_list, SIGNAL(activated(QModelIndex)), SLOT(activated(QModelIndex)));
  153. loadFinished();
  154. }
  155. void FbNotesWidget::activated(const QModelIndex &index)
  156. {
  157. if (FbNotesModel *m = qobject_cast<FbNotesModel*>(m_list->model())) {
  158. m->at(index).select();
  159. }
  160. }
  161. void FbNotesWidget::loadFinished()
  162. {
  163. if (QAbstractItemModel *m = m_list->model()) m->deleteLater();
  164. m_view->load(QUrl());
  165. m_list->setModel(new FbNotesModel(m_text->page(), this));
  166. m_list->reset();
  167. m_list->setColumnHidden(0, true);
  168. }
  169. void FbNotesWidget::showCurrent(const QString &name)
  170. {
  171. QWebElement element = m_text->body().findFirst(name);
  172. QString html = element.toInnerXml();
  173. html.prepend(
  174. "<fb:body name=notes style='padding:0;margin:0;'>"
  175. "<fb:section id=0 style='border:0;padding:0;margin:0;'>"
  176. );
  177. html.append("</fb:section></fb:body>");
  178. m_view->setHtml(html, m_view->url());
  179. }