fb2view.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include "fb2view.hpp"
  2. #include "fb2note.hpp"
  3. #include "fb2read.hpp"
  4. #include "fb2save.h"
  5. #include "fb2utils.h"
  6. #include "fb2xml2.h"
  7. #include <QAction>
  8. #include <QtDebug>
  9. #include <QFileDialog>
  10. #include <QNetworkRequest>
  11. #include <QToolTip>
  12. #include <QWebElement>
  13. #include <QWebFrame>
  14. #include <QWebPage>
  15. //---------------------------------------------------------------------------
  16. // Fb2WebPage
  17. //---------------------------------------------------------------------------
  18. Fb2WebPage::Fb2WebPage(QObject *parent)
  19. : QWebPage(parent)
  20. {
  21. setContentEditable(true);
  22. QWebSettings *s = settings();
  23. s->setAttribute(QWebSettings::AutoLoadImages, true);
  24. s->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
  25. s->setAttribute(QWebSettings::JavaEnabled, false);
  26. s->setAttribute(QWebSettings::JavascriptEnabled, true);
  27. s->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);
  28. s->setAttribute(QWebSettings::PluginsEnabled, false);
  29. s->setAttribute(QWebSettings::ZoomTextOnly, true);
  30. s->setUserStyleSheetUrl(QUrl::fromLocalFile(":style.css"));
  31. // Fb2NetworkDiskCache * cache = new Fb2NetworkDiskCache(this);
  32. // cache->setCacheDirectory("/home/user/tmp/");
  33. // networkAccessManager()->setCache(cache);
  34. }
  35. bool Fb2WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
  36. {
  37. Q_UNUSED(frame);
  38. if (type == NavigationTypeLinkClicked) {
  39. qCritical() << request.url().fragment();
  40. return false;
  41. // QToolTip::showText(request.url().fragment());
  42. }
  43. return QWebPage::acceptNavigationRequest(frame, request, type);
  44. }
  45. //---------------------------------------------------------------------------
  46. // Fb2WebView
  47. //---------------------------------------------------------------------------
  48. Fb2WebView::Fb2WebView(QWidget *parent)
  49. : Fb2BaseWebView(parent)
  50. , m_thread(0)
  51. {
  52. setPage(new Fb2WebPage(this));
  53. page()->setNetworkAccessManager(new Fb2NetworkAccessManager(*this));
  54. connect(page(), SIGNAL(contentsChanged()), this, SLOT(fixContents()));
  55. connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this, SLOT(linkHovered(QString,QString,QString)));
  56. }
  57. Fb2WebView::~Fb2WebView()
  58. {
  59. }
  60. QWebElement Fb2WebView::doc()
  61. {
  62. return page()->mainFrame()->documentElement();
  63. }
  64. QString Fb2WebView::toBodyXml()
  65. {
  66. QWebElement body = doc().findFirst("body");
  67. if (body.isNull()) return QString();
  68. return body.toOuterXml();
  69. }
  70. void Fb2WebView::fixContents()
  71. {
  72. foreach (QWebElement span, doc().findAll("span.apple-style-span[style]")) {
  73. span.removeAttribute("style");
  74. }
  75. }
  76. #include <QLabel>
  77. void Fb2WebView::linkHovered(const QString &link, const QString &title, const QString &textContent)
  78. {
  79. Q_UNUSED(title);
  80. Q_UNUSED(textContent);
  81. QToolTip::showText(QPoint(100, 100), link);
  82. QUrl url = link;
  83. const QString href = url.fragment();
  84. QString query = QString("DIV[id=%1]").arg(href);
  85. QWebElement element = doc().findFirst(query);
  86. if (element.isNull()) return;
  87. QRect rect = element.geometry();
  88. QImage image(rect.size(), QImage::Format_ARGB32);
  89. QPainter painter(&image);
  90. painter.fillRect(rect, QColor("white"));
  91. element.render(&painter);
  92. painter.end();
  93. QLabel * label = new QLabel();
  94. label->setPixmap(QPixmap::fromImage(image));
  95. // label->setText(element.toOuterXml());
  96. label->show();
  97. }
  98. void Fb2WebView::load(const QString &filename, const QString &xml)
  99. {
  100. if (m_thread) return;
  101. m_thread = new Fb2ReadThread(this, filename, xml);
  102. m_thread->start();
  103. }
  104. bool Fb2WebView::save(QIODevice *device)
  105. {
  106. Fb2SaveHandler handler(*this, device);
  107. QXmlInputSource source;
  108. source.setData(toBodyXml());
  109. XML2::HtmlReader reader;
  110. reader.setContentHandler(&handler);
  111. reader.setErrorHandler(&handler);
  112. return reader.parse(source);
  113. }
  114. bool Fb2WebView::save(QByteArray *array, QList<int> *folds)
  115. {
  116. Fb2SaveHandler handler(*this, array, folds);
  117. QXmlInputSource source;
  118. source.setData(toBodyXml());
  119. XML2::HtmlReader reader;
  120. reader.setContentHandler(&handler);
  121. reader.setErrorHandler(&handler);
  122. return reader.parse(source);
  123. }
  124. bool Fb2WebView::save(QString *string)
  125. {
  126. // Use class QByteArray instead QString
  127. // to store information about encoding.
  128. QByteArray data;
  129. bool ok = save(&data);
  130. if (ok) *string = QString::fromUtf8(data.data());
  131. return ok;
  132. }
  133. QString Fb2WebView::temp(QString name)
  134. {
  135. return m_files.get(name).fileName();
  136. }
  137. void Fb2WebView::data(QString name, QByteArray data)
  138. {
  139. m_files.set(name, data);
  140. }
  141. void Fb2WebView::html(QString name, QString html)
  142. {
  143. setHtml(html, QUrl::fromLocalFile(name));
  144. if (m_thread) m_thread->deleteLater();
  145. m_thread = 0;
  146. }
  147. void Fb2WebView::zoomIn()
  148. {
  149. qreal zoom = zoomFactor();
  150. setZoomFactor(zoom * 1.1);
  151. }
  152. void Fb2WebView::zoomOut()
  153. {
  154. qreal zoom = zoomFactor();
  155. setZoomFactor(zoom * 0.9);
  156. }
  157. void Fb2WebView::zoomOrig()
  158. {
  159. setZoomFactor(1);
  160. }
  161. bool Fb2WebView::UndoEnabled()
  162. {
  163. return pageAction(QWebPage::Undo)->isEnabled();
  164. }
  165. bool Fb2WebView::RedoEnabled()
  166. {
  167. return pageAction(QWebPage::Redo)->isEnabled();
  168. }
  169. bool Fb2WebView::CutEnabled()
  170. {
  171. return pageAction(QWebPage::Cut)->isEnabled();
  172. }
  173. bool Fb2WebView::CopyEnabled()
  174. {
  175. return pageAction(QWebPage::Copy)->isEnabled();
  176. }
  177. bool Fb2WebView::BoldChecked()
  178. {
  179. return pageAction(QWebPage::ToggleBold)->isChecked();
  180. }
  181. bool Fb2WebView::ItalicChecked()
  182. {
  183. return pageAction(QWebPage::ToggleItalic)->isChecked();
  184. }
  185. bool Fb2WebView::StrikeChecked()
  186. {
  187. return pageAction(QWebPage::ToggleStrikethrough)->isChecked();
  188. }
  189. bool Fb2WebView::SubChecked()
  190. {
  191. return pageAction(QWebPage::ToggleSubscript)->isChecked();
  192. }
  193. bool Fb2WebView::SupChecked()
  194. {
  195. return pageAction(QWebPage::ToggleSuperscript)->isChecked();
  196. }
  197. void Fb2WebView::insertImage()
  198. {
  199. QString filters;
  200. filters += tr("Common Graphics (*.png *.jpg *.jpeg *.gif);;");
  201. filters += tr("Portable Network Graphics (PNG) (*.png);;");
  202. filters += tr("JPEG (*.jpg *.jpeg);;");
  203. filters += tr("Graphics Interchange Format (*.gif);;");
  204. filters += tr("All Files (*)");
  205. QString fn = QFileDialog::getOpenFileName(this, tr("Open image..."), QString(), filters);
  206. if (fn.isEmpty()) return;
  207. if (!QFile::exists(fn)) return;
  208. QUrl url = QUrl::fromLocalFile(fn);
  209. execCommand("insertImage", url.toString());
  210. }
  211. void Fb2WebView::insertNote()
  212. {
  213. Fb2NoteDlg * dlg = new Fb2NoteDlg(*this);
  214. dlg->setModal(true);
  215. dlg->show();
  216. }
  217. void Fb2WebView::insertLink()
  218. {
  219. }
  220. void Fb2WebView::execCommand(const QString &cmd, const QString &arg)
  221. {
  222. QString javascript = QString("document.execCommand(\"%1\",false,\"%2\")").arg(cmd).arg(arg);
  223. page()->mainFrame()->evaluateJavaScript(javascript);
  224. }
  225. QString Fb2WebView::status()
  226. {
  227. static const QString javascript = FB2::read(":/js/get_status.js");
  228. return page()->mainFrame()->evaluateJavaScript(javascript).toString();
  229. return QString();
  230. }