newnotedialog.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #include "newnotedialog.h"
  2. #include <QHBoxLayout>
  3. #include <QLineEdit>
  4. #include <QComboBox>
  5. #include <QFormLayout>
  6. #include <QPushButton>
  7. #include <QPlainTextEdit>
  8. #include "notebook/notebook.h"
  9. #include "notebook/node.h"
  10. #include "../widgetsfactory.h"
  11. #include <utils/pathutils.h>
  12. #include <utils/fileutils.h>
  13. #include "exception.h"
  14. #include "nodeinfowidget.h"
  15. #include <utils/widgetutils.h>
  16. #include <core/templatemgr.h>
  17. #include <snippet/snippetmgr.h>
  18. using namespace vnotex;
  19. QString NewNoteDialog::s_lastTemplate;
  20. NewNoteDialog::NewNoteDialog(Node *p_node, QWidget *p_parent)
  21. : ScrollDialog(p_parent)
  22. {
  23. Q_ASSERT(p_node && p_node->isLoaded());
  24. setupUI(p_node);
  25. initDefaultValues(p_node);
  26. m_infoWidget->getNameLineEdit()->setFocus();
  27. }
  28. void NewNoteDialog::setupUI(const Node *p_node)
  29. {
  30. setupNodeInfoWidget(p_node, this);
  31. setCentralWidget(m_infoWidget);
  32. auto infoLayout = m_infoWidget->getMainLayout();
  33. {
  34. auto templateLayout = new QHBoxLayout();
  35. templateLayout->setContentsMargins(0, 0, 0, 0);
  36. infoLayout->addRow(tr("Template:"), templateLayout);
  37. setupTemplateComboBox(m_infoWidget);
  38. templateLayout->addWidget(m_templateComboBox);
  39. templateLayout->addStretch();
  40. auto manageBtn = new QPushButton(tr("Manage"), m_infoWidget);
  41. templateLayout->addWidget(manageBtn);
  42. connect(manageBtn, &QPushButton::clicked,
  43. this, []() {
  44. WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(TemplateMgr::getInst().getTemplateFolder()));
  45. });
  46. m_templateTextEdit = WidgetsFactory::createPlainTextConsole(m_infoWidget);
  47. infoLayout->addRow("", m_templateTextEdit);
  48. m_templateTextEdit->hide();
  49. }
  50. setDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
  51. setWindowTitle(tr("New Note"));
  52. }
  53. void NewNoteDialog::setupNodeInfoWidget(const Node *p_node, QWidget *p_parent)
  54. {
  55. m_infoWidget = new NodeInfoWidget(p_node, Node::Flag::Content, p_parent);
  56. }
  57. bool NewNoteDialog::validateInputs()
  58. {
  59. bool valid = true;
  60. QString msg;
  61. valid = valid && validateNameInput(msg);
  62. setInformationText(msg, valid ? ScrollDialog::InformationLevel::Info
  63. : ScrollDialog::InformationLevel::Error);
  64. return valid;
  65. }
  66. bool NewNoteDialog::validateNameInput(QString &p_msg)
  67. {
  68. p_msg.clear();
  69. auto name = m_infoWidget->getName();
  70. if (name.isEmpty() || !PathUtils::isLegalFileName(name)) {
  71. p_msg = tr("Please specify a valid name for the note.");
  72. return false;
  73. }
  74. if (!m_infoWidget->getParentNode()->isLegalNameForNewChild(name)) {
  75. p_msg = tr("Name conflicts with existing or built-in note.");
  76. return false;
  77. }
  78. return true;
  79. }
  80. void NewNoteDialog::acceptedButtonClicked()
  81. {
  82. s_lastTemplate = m_templateComboBox->currentData().toString();
  83. if (validateInputs() && newNote()) {
  84. accept();
  85. }
  86. }
  87. bool NewNoteDialog::newNote()
  88. {
  89. m_newNode.clear();
  90. Notebook *notebook = const_cast<Notebook *>(m_infoWidget->getNotebook());
  91. Node *parentNode = const_cast<Node *>(m_infoWidget->getParentNode());
  92. try {
  93. m_newNode = notebook->newNode(parentNode,
  94. Node::Flag::Content,
  95. m_infoWidget->getName(),
  96. getTemplateContent());
  97. } catch (Exception &p_e) {
  98. QString msg = tr("Failed to create note under (%1) in (%2) (%3).").arg(parentNode->getName(),
  99. notebook->getName(),
  100. p_e.what());
  101. qCritical() << msg;
  102. setInformationText(msg, ScrollDialog::InformationLevel::Error);
  103. return false;
  104. }
  105. emit notebook->nodeUpdated(m_newNode.data());
  106. return true;
  107. }
  108. const QSharedPointer<Node> &NewNoteDialog::getNewNode() const
  109. {
  110. return m_newNode;
  111. }
  112. void NewNoteDialog::initDefaultValues(const Node *p_node)
  113. {
  114. {
  115. auto lineEdit = m_infoWidget->getNameLineEdit();
  116. auto defaultName = FileUtils::generateFileNameWithSequence(p_node->fetchAbsolutePath(),
  117. tr("note"),
  118. QStringLiteral("md"));
  119. lineEdit->setText(defaultName);
  120. WidgetUtils::selectBaseName(lineEdit);
  121. }
  122. if (!s_lastTemplate.isEmpty()) {
  123. // Restore.
  124. int idx = m_templateComboBox->findData(s_lastTemplate);
  125. if (idx != -1) {
  126. m_templateComboBox->setCurrentIndex(idx);
  127. } else {
  128. s_lastTemplate.clear();
  129. }
  130. }
  131. }
  132. void NewNoteDialog::setupTemplateComboBox(QWidget *p_parent)
  133. {
  134. m_templateComboBox = WidgetsFactory::createComboBox(p_parent);
  135. // None.
  136. m_templateComboBox->addItem(tr("None"), "");
  137. int idx = 1;
  138. auto templates = TemplateMgr::getInst().getTemplates();
  139. for (const auto &temp : templates) {
  140. m_templateComboBox->addItem(temp, temp);
  141. m_templateComboBox->setItemData(idx++, temp, Qt::ToolTipRole);
  142. }
  143. m_templateComboBox->setCurrentIndex(0);
  144. connect(m_templateComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
  145. this, &NewNoteDialog::updateCurrentTemplate);
  146. }
  147. QString NewNoteDialog::getTemplateContent() const
  148. {
  149. int cursorOffset = 0;
  150. return SnippetMgr::getInst().applySnippetBySymbol(m_templateContent,
  151. QString(),
  152. cursorOffset,
  153. SnippetMgr::generateOverrides(m_infoWidget->getName()));
  154. }
  155. void NewNoteDialog::updateCurrentTemplate()
  156. {
  157. m_templateContent.clear();
  158. m_templateTextEdit->clear();
  159. auto temp = m_templateComboBox->currentData().toString();
  160. if (temp.isEmpty()) {
  161. m_templateTextEdit->hide();
  162. return;
  163. }
  164. const auto filePath = TemplateMgr::getInst().getTemplateFilePath(temp);
  165. try {
  166. m_templateContent = FileUtils::readTextFile(filePath);
  167. m_templateTextEdit->setPlainText(m_templateContent);
  168. m_templateTextEdit->show();
  169. } catch (Exception &p_e) {
  170. m_templateTextEdit->hide();
  171. QString msg = tr("Failed to load template (%1) (%2).")
  172. .arg(filePath, p_e.what());
  173. qCritical() << msg;
  174. setInformationText(msg, ScrollDialog::InformationLevel::Error);
  175. }
  176. }