managenotebooksdialog.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include "managenotebooksdialog.h"
  2. #include <QHBoxLayout>
  3. #include <QVBoxLayout>
  4. #include <QScrollArea>
  5. #include <QListWidgetItem>
  6. #include <QMenu>
  7. #include <QTimer>
  8. #include <QPushButton>
  9. #include "notebook/notebook.h"
  10. #include "notebookinfowidget.h"
  11. #include "vnotex.h"
  12. #include "notebookmgr.h"
  13. #include "../messageboxhelper.h"
  14. #include <utils/iconutils.h>
  15. #include <utils/utils.h>
  16. #include <utils/widgetutils.h>
  17. #include "../widgetsfactory.h"
  18. #include "exception.h"
  19. #include "../propertydefs.h"
  20. #include "../listwidget.h"
  21. #include <core/configmgr.h>
  22. using namespace vnotex;
  23. ManageNotebooksDialog::ManageNotebooksDialog(const Notebook *p_notebook, QWidget *p_parent)
  24. : Dialog(p_parent)
  25. {
  26. setupUI();
  27. loadNotebooks(p_notebook);
  28. }
  29. void ManageNotebooksDialog::setupUI()
  30. {
  31. auto widget = new QWidget(this);
  32. setCentralWidget(widget);
  33. auto mainLayout = new QHBoxLayout(widget);
  34. setupNotebookList(widget);
  35. mainLayout->addWidget(m_notebookList);
  36. mainLayout->setStretchFactor(m_notebookList, 1);
  37. {
  38. m_infoScrollArea = new QScrollArea(widget);
  39. m_infoScrollArea->setWidgetResizable(true);
  40. mainLayout->addWidget(m_infoScrollArea);
  41. mainLayout->setStretchFactor(m_infoScrollArea, 3);
  42. auto infoWidget = new QWidget(widget);
  43. m_infoScrollArea->setWidget(infoWidget);
  44. auto infoLayout = new QVBoxLayout(infoWidget);
  45. setupNotebookInfoWidget(infoWidget);
  46. infoLayout->addWidget(m_notebookInfoWidget);
  47. auto btnLayout = new QHBoxLayout();
  48. infoLayout->addLayout(btnLayout);
  49. m_closeNotebookBtn = new QPushButton(tr("Close"), infoWidget);
  50. btnLayout->addStretch();
  51. btnLayout->addWidget(m_closeNotebookBtn);
  52. connect(m_closeNotebookBtn, &QPushButton::clicked,
  53. this, [this]() {
  54. if (checkUnsavedChanges()) {
  55. return;
  56. }
  57. closeNotebook(m_notebookInfoWidget->getNotebook());
  58. });
  59. m_deleteNotebookBtn = new QPushButton(tr("Delete (DANGER)"), infoWidget);
  60. WidgetUtils::setPropertyDynamically(m_deleteNotebookBtn, PropertyDefs::c_dangerButton, true);
  61. btnLayout->addWidget(m_deleteNotebookBtn);
  62. connect(m_deleteNotebookBtn, &QPushButton::clicked,
  63. this, [this]() {
  64. if (checkUnsavedChanges()) {
  65. return;
  66. }
  67. removeNotebook(m_notebookInfoWidget->getNotebook());
  68. });
  69. }
  70. setDialogButtonBox(QDialogButtonBox::Ok
  71. | QDialogButtonBox::Apply
  72. | QDialogButtonBox::Reset
  73. | QDialogButtonBox::Cancel);
  74. setWindowTitle(tr("Manage Notebooks"));
  75. }
  76. Notebook *ManageNotebooksDialog::getNotebookFromItem(const QListWidgetItem *p_item) const
  77. {
  78. Notebook *notebook = nullptr;
  79. if (p_item) {
  80. auto id = static_cast<ID>(p_item->data(Qt::UserRole).toULongLong());
  81. notebook = VNoteX::getInst().getNotebookMgr().findNotebookById(id).data();
  82. }
  83. return notebook;
  84. }
  85. void ManageNotebooksDialog::setupNotebookList(QWidget *p_parent)
  86. {
  87. m_notebookList = new ListWidget(p_parent);
  88. connect(m_notebookList, &QListWidget::currentItemChanged,
  89. this, [this](QListWidgetItem *p_item, QListWidgetItem *p_previous) {
  90. auto notebook = getNotebookFromItem(p_item);
  91. if (m_changesUnsaved) {
  92. // Have unsaved changes.
  93. if (m_notebook != notebook) {
  94. checkUnsavedChanges();
  95. QTimer::singleShot(50, this, [this, p_previous]() {
  96. m_notebookList->setCurrentItem(p_previous);
  97. });
  98. }
  99. return;
  100. }
  101. m_notebook = notebook;
  102. selectNotebook(m_notebook);
  103. });
  104. }
  105. void ManageNotebooksDialog::setupNotebookInfoWidget(QWidget *p_parent)
  106. {
  107. m_notebookInfoWidget = new NotebookInfoWidget(NotebookInfoWidget::Edit, p_parent);
  108. connect(m_notebookInfoWidget, &NotebookInfoWidget::basicInfoEdited,
  109. this, [this]() {
  110. bool unsaved = false;
  111. if (m_notebook) {
  112. if (m_notebook->getName() != m_notebookInfoWidget->getName()
  113. || m_notebook->getDescription() != m_notebookInfoWidget->getDescription()) {
  114. unsaved = true;
  115. }
  116. }
  117. setChangesUnsaved(unsaved);
  118. });
  119. }
  120. void ManageNotebooksDialog::loadNotebooks(const Notebook *p_notebook)
  121. {
  122. setChangesUnsaved(false);
  123. m_notebookList->clear();
  124. bool hasCurrentItem = false;
  125. auto &notebookMgr = VNoteX::getInst().getNotebookMgr();
  126. const auto &notebooks = notebookMgr.getNotebooks();
  127. for (auto &nb : notebooks) {
  128. auto item = new QListWidgetItem(nb->getName());
  129. item->setData(Qt::UserRole, nb->getId());
  130. item->setToolTip(nb->getName());
  131. m_notebookList->addItem(item);
  132. if (nb.data() == p_notebook) {
  133. hasCurrentItem = true;
  134. m_notebookList->setCurrentItem(item, QItemSelectionModel::ClearAndSelect);
  135. }
  136. }
  137. if (!hasCurrentItem) {
  138. if (notebooks.isEmpty()) {
  139. selectNotebook(nullptr);
  140. } else {
  141. m_notebookList->setCurrentRow(0);
  142. }
  143. }
  144. }
  145. void ManageNotebooksDialog::selectNotebook(Notebook *p_notebook)
  146. {
  147. m_notebookInfoWidget->setNotebook(p_notebook);
  148. setChangesUnsaved(false);
  149. // Update buttons.
  150. m_closeNotebookBtn->setEnabled(p_notebook);
  151. m_deleteNotebookBtn->setEnabled(p_notebook);
  152. WidgetUtils::resizeToHideScrollBarLater(m_infoScrollArea, false, true);
  153. }
  154. void ManageNotebooksDialog::acceptedButtonClicked()
  155. {
  156. if (saveChangesToNotebook()) {
  157. accept();
  158. }
  159. }
  160. void ManageNotebooksDialog::resetButtonClicked()
  161. {
  162. m_notebookInfoWidget->clear();
  163. selectNotebook(m_notebook);
  164. }
  165. void ManageNotebooksDialog::appliedButtonClicked()
  166. {
  167. Q_ASSERT(m_changesUnsaved);
  168. if (saveChangesToNotebook()) {
  169. loadNotebooks(m_notebook);
  170. }
  171. }
  172. void ManageNotebooksDialog::setChangesUnsaved(bool p_unsaved)
  173. {
  174. m_changesUnsaved = p_unsaved;
  175. setButtonEnabled(QDialogButtonBox::Apply, m_changesUnsaved);
  176. setButtonEnabled(QDialogButtonBox::Reset, m_changesUnsaved);
  177. }
  178. bool ManageNotebooksDialog::validateInputs()
  179. {
  180. bool valid = true;
  181. QString msg;
  182. valid = valid && validateNameInput(msg);
  183. setInformationText(msg, valid ? Dialog::InformationLevel::Info
  184. : Dialog::InformationLevel::Error);
  185. return valid;
  186. }
  187. bool ManageNotebooksDialog::validateNameInput(QString &p_msg)
  188. {
  189. if (m_notebookInfoWidget->getName().isEmpty()) {
  190. Utils::appendMsg(p_msg, tr("Please specify a name for the notebook."));
  191. return false;
  192. }
  193. return true;
  194. }
  195. bool ManageNotebooksDialog::saveChangesToNotebook()
  196. {
  197. if (!m_changesUnsaved || !m_notebook) {
  198. return true;
  199. }
  200. if (!validateInputs()) {
  201. return false;
  202. }
  203. m_notebook->updateName(m_notebookInfoWidget->getName());
  204. m_notebook->updateDescription(m_notebookInfoWidget->getDescription());
  205. return true;
  206. }
  207. void ManageNotebooksDialog::closeNotebook(const Notebook *p_notebook)
  208. {
  209. if (!p_notebook) {
  210. return;
  211. }
  212. int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Question,
  213. tr("Close notebook (%1)?")
  214. .arg(p_notebook->getName()),
  215. tr("The notebook could be imported again later."),
  216. tr("Notebook location: %1").arg(p_notebook->getRootFolderAbsolutePath()),
  217. this);
  218. if (ret != QMessageBox::Ok) {
  219. return;
  220. }
  221. try
  222. {
  223. VNoteX::getInst().getNotebookMgr().closeNotebook(p_notebook->getId());
  224. } catch (Exception &p_e) {
  225. MessageBoxHelper::notify(MessageBoxHelper::Warning,
  226. tr("Failed to close notebook (%1)").arg(p_e.what()),
  227. this);
  228. loadNotebooks(nullptr);
  229. return;
  230. }
  231. loadNotebooks(nullptr);
  232. }
  233. void ManageNotebooksDialog::removeNotebook(const Notebook *p_notebook)
  234. {
  235. if (!p_notebook) {
  236. return;
  237. }
  238. int ret = MessageBoxHelper::questionOkCancel(MessageBoxHelper::Warning,
  239. tr("Delete notebook (%1) from disk?").arg(p_notebook->getName()),
  240. tr("CALM DOWN! CALM DOWN! CALM DOWN! It will delete all files belonging to this notebook from disk. "
  241. "It is dangerous since it will bypass system's recycle bin!"),
  242. tr("Notebook location: %1\nUse the \"Close\" button if you just want to remove it from %2.")
  243. .arg(p_notebook->getRootFolderAbsolutePath())
  244. .arg(ConfigMgr::c_appName),
  245. this);
  246. if (ret != QMessageBox::Ok) {
  247. return;
  248. }
  249. try {
  250. VNoteX::getInst().getNotebookMgr().removeNotebook(p_notebook->getId());
  251. } catch (Exception &p_e) {
  252. MessageBoxHelper::notify(MessageBoxHelper::Warning,
  253. tr("Failed to delete notebook (%1)").arg(p_e.what()),
  254. this);
  255. loadNotebooks(nullptr);
  256. return;
  257. }
  258. loadNotebooks(nullptr);
  259. }
  260. bool ManageNotebooksDialog::checkUnsavedChanges()
  261. {
  262. if (m_changesUnsaved) {
  263. MessageBoxHelper::notify(MessageBoxHelper::Warning,
  264. tr("There are unsaved changes to current notebook."),
  265. this);
  266. return true;
  267. }
  268. return false;
  269. }