fb2dock.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "fb2dock.hpp"
  2. #include "fb2code.hpp"
  3. #include "fb2head.hpp"
  4. #include "fb2page.hpp"
  5. #include "fb2text.hpp"
  6. #include <QLayout>
  7. #include <QtDebug>
  8. //---------------------------------------------------------------------------
  9. // FbModeAction
  10. //---------------------------------------------------------------------------
  11. FbModeAction::FbModeAction(FbMainDock *parent, Fb::Mode mode, const QIcon &icon, const QString &text)
  12. : QAction(icon, text, parent)
  13. , m_dock(parent)
  14. , m_mode(mode)
  15. {
  16. setCheckable(true);
  17. connect(this, SIGNAL(triggered()), SLOT(switchMode()));
  18. }
  19. FbModeAction::FbModeAction(FbMainDock *parent, Fb::Mode mode, const QString &text)
  20. : QAction(text, parent)
  21. , m_dock(parent)
  22. , m_mode(mode)
  23. {
  24. setCheckable(true);
  25. connect(this, SIGNAL(triggered()), SLOT(switchMode()));
  26. }
  27. void FbModeAction::switchMode()
  28. {
  29. m_dock->switchMode(m_mode);
  30. }
  31. //---------------------------------------------------------------------------
  32. // FbMainDock
  33. //---------------------------------------------------------------------------
  34. FbMainDock::FbMainDock(QWidget *parent)
  35. : QStackedWidget(parent)
  36. , isSwitched(false)
  37. {
  38. textFrame = new FbTextFrame(this);
  39. m_text = new FbTextEdit(textFrame, parent);
  40. textFrame->layout()->addWidget(m_text);
  41. m_head = new FbHeadEdit(this, m_text);
  42. m_code = new FbCodeEdit(this);
  43. addWidget(textFrame);
  44. addWidget(m_head);
  45. addWidget(m_code);
  46. connect(m_text->page(), SIGNAL(warning(int,int,QString)), parent, SLOT(warning(int,int,QString)));
  47. connect(m_text->page(), SIGNAL(error(int,int,QString)), parent, SLOT(error(int,int,QString)));
  48. connect(m_text->page(), SIGNAL(fatal(int,int,QString)), parent, SLOT(fatal(int,int,QString)));
  49. connect(m_text->page(), SIGNAL(error(int,int,QString)), SLOT(error(int,int)));
  50. connect(m_text->page(), SIGNAL(fatal(int,int,QString)), SLOT(error(int,int)));
  51. connect(m_text->page(), SIGNAL(status(QString)), parent, SLOT(status(QString)));
  52. connect(m_text, SIGNAL(modificationChanged(bool)), SLOT(textChanged(bool)));
  53. connect(m_head, SIGNAL(modificationChanged(bool)), SLOT(textChanged(bool)));
  54. connect(m_code, SIGNAL(modificationChanged(bool)), SLOT(textChanged(bool)));
  55. connect(m_head, SIGNAL(status(QString)), parent, SLOT(status(QString)));
  56. connect(m_code, SIGNAL(status(QString)), parent, SLOT(status(QString)));
  57. connect(this, SIGNAL(status(QString)), parent, SLOT(status(QString)));
  58. }
  59. void FbMainDock::switchMode(Fb::Mode mode)
  60. {
  61. if (mode == m_mode) return;
  62. isSwitched = isModified();
  63. if (currentWidget() == m_code) {
  64. QString xml = m_code->toPlainText();
  65. switch (m_mode) {
  66. case Fb::Code: m_text->page()->read(xml); break;
  67. case Fb::Html: m_text->setHtml(xml, m_text->url()); break;
  68. default: ;
  69. }
  70. } else {
  71. switch (mode) {
  72. case Fb::Code: {
  73. QString xml; int anchor, focus;
  74. m_text->save(&xml, anchor, focus);
  75. m_code->setPlainText(xml);
  76. QTextCursor cursor = m_code->textCursor();
  77. if (anchor > 0) cursor.setPosition(anchor, QTextCursor::MoveAnchor);
  78. if (focus > 0) cursor.setPosition(focus, QTextCursor::KeepAnchor);
  79. m_code->setTextCursor(cursor);
  80. } break;
  81. case Fb::Html: {
  82. QString html = m_text->toHtml();
  83. m_code->setPlainText(html);
  84. } break;
  85. default: ;
  86. }
  87. }
  88. setMode(mode);
  89. }
  90. void FbMainDock::setMode(Fb::Mode mode)
  91. {
  92. enableMenu(mode == Fb::Text);
  93. switch (m_mode = mode) {
  94. case Fb::Text: setModeText(); break;
  95. case Fb::Head: setModeHead(); break;
  96. case Fb::Code: setModeCode(); break;
  97. case Fb::Html: setModeHtml(); break;
  98. }
  99. m_actions[mode]->setChecked(true);
  100. emit status(QString());
  101. }
  102. void FbMainDock::setModeText()
  103. {
  104. m_mode = Fb::Text;
  105. setCurrentWidget(textFrame);
  106. m_head->disconnectActions();
  107. m_code->disconnectActions();
  108. m_text->connectActions(m_tool);
  109. m_text->viewContents(true);
  110. }
  111. void FbMainDock::setModeHead()
  112. {
  113. m_mode = Fb::Head;
  114. m_text->hideDocks();
  115. setCurrentWidget(m_head);
  116. m_text->disconnectActions();
  117. m_code->disconnectActions();
  118. m_head->connectActions(m_tool);
  119. m_head->updateTree();
  120. }
  121. void FbMainDock::setModeCode()
  122. {
  123. m_mode = Fb::Code;
  124. m_text->hideDocks();
  125. setCurrentWidget(m_code);
  126. m_text->disconnectActions();
  127. m_head->disconnectActions();
  128. m_code->connectActions(m_tool);
  129. }
  130. void FbMainDock::setModeHtml()
  131. {
  132. m_mode = Fb::Html;
  133. m_text->hideDocks();
  134. setCurrentWidget(m_code);
  135. m_text->disconnectActions();
  136. m_head->disconnectActions();
  137. m_code->connectActions(m_tool);
  138. }
  139. void FbMainDock::error(int row, int col)
  140. {
  141. m_code->setCursor(row, col);
  142. setMode(Fb::Code);
  143. }
  144. bool FbMainDock::load(const QString &filename)
  145. {
  146. QFile *file = new QFile(filename);
  147. if (!file->open(QFile::ReadOnly | QFile::Text)) {
  148. qCritical() << QObject::tr("Cannot read file %1: %2.").arg(filename).arg(file->errorString());
  149. delete file;
  150. return false;
  151. }
  152. if (currentWidget() == m_code) {
  153. m_code->clear();
  154. return m_code->read(file);
  155. } else {
  156. m_text->page()->read(file);
  157. }
  158. return false;
  159. }
  160. bool FbMainDock::save(QIODevice *device, const QString &codec)
  161. {
  162. if (currentWidget() == m_code) {
  163. QTextStream out(device);
  164. out << m_code->toPlainText();
  165. } else {
  166. isSwitched = false;
  167. m_text->save(device, codec);
  168. }
  169. return true;
  170. }
  171. void FbMainDock::textChanged(bool changed)
  172. {
  173. emit modificationChanged(isSwitched || changed);
  174. }
  175. bool FbMainDock::isModified() const
  176. {
  177. if (isSwitched) return true;
  178. QWidget * current = currentWidget();
  179. if (current == textFrame) return m_text->isModified();
  180. if (current == m_head) return m_text->isModified();
  181. if (current == m_code) return m_code->isModified();
  182. return false;
  183. }
  184. void FbMainDock::addAction(Fb::Mode mode, QAction *action)
  185. {
  186. m_actions.insert(mode, action);
  187. }
  188. void FbMainDock::addMenu(QMenu *menu)
  189. {
  190. m_menus.append(menu);
  191. }
  192. void FbMainDock::enableMenu(bool value)
  193. {
  194. for (QMenu *menu: m_menus) {
  195. menu->setEnabled(value);
  196. }
  197. }