1
0

fb2html.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "fb2html.h"
  2. #include "fb2utils.h"
  3. #include "fb2text.hpp"
  4. //---------------------------------------------------------------------------
  5. // Fb2TextElement
  6. //---------------------------------------------------------------------------
  7. void Fb2TextElement::getChildren(Fb2ElementList &list)
  8. {
  9. Fb2TextElement child = firstChild();
  10. while (!child.isNull()) {
  11. QString tag = child.tagName().toLower();
  12. if (tag == "div") {
  13. if (child.hasAttribute("class")) list << child;
  14. } else if (tag == "img") {
  15. list << child;
  16. } else {
  17. child.getChildren(list);
  18. }
  19. child = child.nextSibling();
  20. }
  21. }
  22. QString Fb2TextElement::location()
  23. {
  24. static const QString javascript = FB2::read(":/js/get_location.js").prepend("var element=this;");
  25. return evaluateJavaScript(javascript).toString();
  26. }
  27. void Fb2TextElement::select()
  28. {
  29. static const QString javascript = FB2::read(":/js/set_cursor.js");
  30. evaluateJavaScript(javascript);
  31. }
  32. bool Fb2TextElement::isBody() const
  33. {
  34. return tagName() == "DIV" && attribute("class").toLower() == "body";
  35. }
  36. bool Fb2TextElement::isSection() const
  37. {
  38. return tagName() == "DIV" && attribute("class").toLower() == "section";
  39. }
  40. bool Fb2TextElement::hasTitle() const
  41. {
  42. return Fb2TextElement(firstChild()).isTitle();
  43. }
  44. bool Fb2TextElement::isTitle() const
  45. {
  46. return tagName() == "DIV" && attribute("class").toLower() == "title";
  47. }
  48. //---------------------------------------------------------------------------
  49. // Fb2UndoCommand
  50. //---------------------------------------------------------------------------
  51. QString Fb2UndoCommand::div(const QString &style, const QString &text)
  52. {
  53. return QString("<div class=%1>%2</div>").arg(style).arg(text);
  54. }
  55. QString Fb2UndoCommand::p(const QString &text)
  56. {
  57. return QString("<p>%1</p>").arg(text);
  58. }
  59. //---------------------------------------------------------------------------
  60. // Fb2AddBodyCmd
  61. //---------------------------------------------------------------------------
  62. void Fb2AddBodyCmd::undo()
  63. {
  64. m_body.takeFromDocument();
  65. m_page.update();
  66. }
  67. void Fb2AddBodyCmd::redo()
  68. {
  69. Fb2TextElement parent = m_page.body();
  70. if (m_body.isNull()) {
  71. QString html = div("body", div("title", p()) + div("section", div("title", p()) + p()));
  72. parent.appendInside(html);
  73. m_body = parent.lastChild();
  74. } else {
  75. parent.appendInside(m_body);
  76. }
  77. m_body.select();
  78. m_page.update();
  79. }
  80. //---------------------------------------------------------------------------
  81. // Fb2SectionCmd
  82. //---------------------------------------------------------------------------
  83. void Fb2SectionCmd::redo()
  84. {
  85. if (m_child.isNull()) {
  86. QString html = div("section", div("title", p()) + p());
  87. m_parent.appendInside(html);
  88. m_child = m_parent.lastChild();
  89. } else {
  90. m_parent.appendInside(m_child);
  91. }
  92. m_child.select();
  93. m_page.update();
  94. }
  95. void Fb2SectionCmd::undo()
  96. {
  97. m_child.takeFromDocument();
  98. Fb2TextElement last = m_parent.lastChild();
  99. if (last.isNull()) {
  100. m_parent.select();
  101. } else {
  102. last.select();
  103. }
  104. m_page.update();
  105. }
  106. //---------------------------------------------------------------------------
  107. // Fb2TitleCmd
  108. //---------------------------------------------------------------------------
  109. void Fb2TitleCmd::redo()
  110. {
  111. if (m_title.isNull()) {
  112. QString html = div("title", p());
  113. m_section.prependInside(html);
  114. m_title = m_section.firstChild();
  115. } else {
  116. m_section.prependInside(m_title);
  117. }
  118. m_section.select();
  119. m_page.update();
  120. }
  121. void Fb2TitleCmd::undo()
  122. {
  123. m_title.takeFromDocument();
  124. m_section.select();
  125. m_page.update();
  126. }
  127. //---------------------------------------------------------------------------
  128. // Fb2SubtitleCmd
  129. //---------------------------------------------------------------------------
  130. void Fb2SubtitleCmd::redo()
  131. {
  132. QString html = "<div class=subtitle><p><br/></p></div>";
  133. Fb2TextElement element = m_page.element(m_location);
  134. if (m_element.isNull()) {
  135. element.appendOutside(html);
  136. } else {
  137. element.appendOutside(m_element);
  138. }
  139. element = element.nextSibling();
  140. m_position = element.location();
  141. element.select();
  142. m_page.update();
  143. }
  144. void Fb2SubtitleCmd::undo()
  145. {
  146. Fb2TextElement element = m_page.element(m_position);
  147. Fb2TextElement parent = element.parent();
  148. m_element = element.takeFromDocument();
  149. parent.select();
  150. m_page.update();
  151. }
  152. //---------------------------------------------------------------------------
  153. // Fb2DeleteCmd
  154. //---------------------------------------------------------------------------
  155. Fb2DeleteCmd::Fb2DeleteCmd(Fb2TextPage &page, const Fb2TextElement &element, Fb2UndoCommand *parent)
  156. : Fb2UndoCommand(parent)
  157. , m_element(element)
  158. , m_page(page)
  159. , m_inner(false)
  160. {
  161. m_parent = element.previousSibling();
  162. if (m_parent.isNull()) {
  163. m_parent = element.parent();
  164. m_inner = true;
  165. }
  166. }
  167. void Fb2DeleteCmd::redo()
  168. {
  169. m_element.takeFromDocument();
  170. m_page.update();
  171. }
  172. void Fb2DeleteCmd::undo()
  173. {
  174. if (m_inner) {
  175. m_parent.prependInside(m_element);
  176. } else {
  177. m_parent.appendOutside(m_element);
  178. }
  179. m_page.update();
  180. }