fb2note.cpp 6.7 KB

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