vnotebookselector.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. #include "vnotebookselector.h"
  2. #include <QDebug>
  3. #include <QJsonObject>
  4. #include <QListWidget>
  5. #include <QAction>
  6. #include <QMenu>
  7. #include "vnotebook.h"
  8. #include "vconfigmanager.h"
  9. #include "dialog/vnewnotebookdialog.h"
  10. #include "dialog/vnotebookinfodialog.h"
  11. #include "vnotebook.h"
  12. #include "vdirectory.h"
  13. #include "utils/vutils.h"
  14. #include "vnote.h"
  15. #include "veditarea.h"
  16. #include "vnofocusitemdelegate.h"
  17. extern VConfigManager vconfig;
  18. const int VNotebookSelector::c_notebookStartIdx = 1;
  19. VNotebookSelector::VNotebookSelector(VNote *vnote, QWidget *p_parent)
  20. : QComboBox(p_parent), m_vnote(vnote), m_notebooks(m_vnote->getNotebooks()),
  21. m_editArea(NULL), m_lastValidIndex(-1)
  22. {
  23. m_listWidget = new QListWidget(this);
  24. m_listWidget->setItemDelegate(new VNoFocusItemDelegate(this));
  25. m_listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
  26. connect(m_listWidget, &QListWidget::customContextMenuRequested,
  27. this, &VNotebookSelector::requestPopupListContextMenu);
  28. setModel(m_listWidget->model());
  29. setView(m_listWidget);
  30. m_listWidget->viewport()->installEventFilter(this);
  31. initActions();
  32. connect(this, SIGNAL(currentIndexChanged(int)),
  33. this, SLOT(handleCurIndexChanged(int)));
  34. connect(this, SIGNAL(activated(int)),
  35. this, SLOT(handleItemActivated(int)));
  36. }
  37. void VNotebookSelector::initActions()
  38. {
  39. m_deleteNotebookAct = new QAction(QIcon(":/resources/icons/delete_notebook.svg"),
  40. tr("&Delete"), this);
  41. m_deleteNotebookAct->setStatusTip(tr("Delete current notebook"));
  42. connect(m_deleteNotebookAct, SIGNAL(triggered(bool)),
  43. this, SLOT(deleteNotebook()));
  44. m_notebookInfoAct = new QAction(QIcon(":/resources/icons/notebook_info.svg"),
  45. tr("&Info"), this);
  46. m_notebookInfoAct->setStatusTip(tr("View and edit current notebook's information"));
  47. connect(m_notebookInfoAct, SIGNAL(triggered(bool)),
  48. this, SLOT(editNotebookInfo()));
  49. }
  50. void VNotebookSelector::updateComboBox()
  51. {
  52. int index = vconfig.getCurNotebookIndex();
  53. disconnect(this, SIGNAL(currentIndexChanged(int)),
  54. this, SLOT(handleCurIndexChanged(int)));
  55. clear();
  56. m_listWidget->clear();
  57. insertAddNotebookItem();
  58. for (int i = 0; i < m_notebooks.size(); ++i) {
  59. addNotebookItem(m_notebooks[i]->getName());
  60. }
  61. setCurrentIndex(-1);
  62. connect(this, SIGNAL(currentIndexChanged(int)),
  63. this, SLOT(handleCurIndexChanged(int)));
  64. if (m_notebooks.isEmpty()) {
  65. vconfig.setCurNotebookIndex(-1);
  66. setCurrentIndex(0);
  67. } else {
  68. setCurrentIndexNotebook(index);
  69. }
  70. qDebug() << "notebooks" << m_notebooks.size() << "current index" << index;
  71. }
  72. void VNotebookSelector::setCurrentIndexNotebook(int p_index)
  73. {
  74. if (p_index > -1) {
  75. p_index += c_notebookStartIdx;
  76. }
  77. setCurrentIndex(p_index);
  78. }
  79. void VNotebookSelector::insertAddNotebookItem()
  80. {
  81. QListWidgetItem *item = new QListWidgetItem();
  82. item->setIcon(QIcon(":/resources/icons/create_notebook.svg"));
  83. item->setText(tr("Add Notebook"));
  84. QFont font;
  85. font.setItalic(true);
  86. item->setData(Qt::FontRole, font);
  87. item->setToolTip(tr("Create or import a notebook"));
  88. m_listWidget->insertItem(0, item);
  89. }
  90. void VNotebookSelector::handleCurIndexChanged(int p_index)
  91. {
  92. qDebug() << "current index changed" << p_index << "startIdx" << c_notebookStartIdx;
  93. VNotebook *nb = NULL;
  94. if (p_index > -1) {
  95. if (p_index < c_notebookStartIdx) {
  96. // Click a special action item.
  97. if (m_listWidget->count() == c_notebookStartIdx) {
  98. // There is no regular notebook item. Just let it be selected.
  99. p_index = -1;
  100. } else {
  101. // handleItemActivated() will handle the logics.
  102. return;
  103. }
  104. } else {
  105. int nbIdx = p_index - c_notebookStartIdx;
  106. Q_ASSERT(nbIdx >= 0);
  107. nb = m_notebooks[nbIdx];
  108. }
  109. }
  110. m_lastValidIndex = p_index;
  111. QString tooltip;
  112. if (p_index > -1) {
  113. p_index -= c_notebookStartIdx;
  114. tooltip = nb->getName();
  115. }
  116. setToolTip(tooltip);
  117. vconfig.setCurNotebookIndex(p_index);
  118. emit curNotebookChanged(nb);
  119. }
  120. void VNotebookSelector::handleItemActivated(int p_index)
  121. {
  122. if (p_index > -1 && p_index < c_notebookStartIdx) {
  123. // Click a special action item
  124. if (m_lastValidIndex > -1) {
  125. setCurrentIndex(m_lastValidIndex);
  126. }
  127. newNotebook();
  128. }
  129. }
  130. void VNotebookSelector::update()
  131. {
  132. updateComboBox();
  133. }
  134. bool VNotebookSelector::newNotebook()
  135. {
  136. QString info;
  137. QString defaultName("new_notebook");
  138. QString defaultPath;
  139. do {
  140. VNewNotebookDialog dialog(tr("Add Notebook"), info, defaultName,
  141. defaultPath, this);
  142. if (dialog.exec() == QDialog::Accepted) {
  143. QString name = dialog.getNameInput();
  144. QString path = dialog.getPathInput();
  145. if (findNotebook(name)) {
  146. info = tr("Name already exists. Please choose another name.");
  147. defaultName = name;
  148. defaultPath = path;
  149. continue;
  150. }
  151. createNotebook(name, path, dialog.getImportCheck());
  152. return true;
  153. }
  154. break;
  155. } while (true);
  156. return false;
  157. }
  158. VNotebook *VNotebookSelector::findNotebook(const QString &p_name)
  159. {
  160. for (int i = 0; i < m_notebooks.size(); ++i) {
  161. if (m_notebooks[i]->getName() == p_name) {
  162. return m_notebooks[i];
  163. }
  164. }
  165. return NULL;
  166. }
  167. void VNotebookSelector::createNotebook(const QString &p_name, const QString &p_path, bool p_import)
  168. {
  169. VNotebook *nb = VNotebook::createNotebook(p_name, p_path, p_import, m_vnote);
  170. m_notebooks.append(nb);
  171. vconfig.setNotebooks(m_notebooks);
  172. addNotebookItem(nb->getName());
  173. setCurrentIndexNotebook(m_notebooks.size() - 1);
  174. }
  175. void VNotebookSelector::deleteNotebook()
  176. {
  177. QList<QListWidgetItem *> items = m_listWidget->selectedItems();
  178. if (items.isEmpty()) {
  179. return;
  180. }
  181. Q_ASSERT(items.size() == 1);
  182. QListWidgetItem *item = items[0];
  183. int index = indexOfListItem(item);
  184. VNotebook *notebook = getNotebookFromComboIndex(index);
  185. Q_ASSERT(notebook);
  186. QString curName = notebook->getName();
  187. QString curPath = notebook->getPath();
  188. int ret = VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
  189. tr("Are you sure to delete notebook %1?").arg(curName),
  190. tr("This will delete any files in this notebook (%1).").arg(curPath),
  191. QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok, this);
  192. if (ret == QMessageBox::Ok) {
  193. m_editArea->closeFile(notebook, true);
  194. deleteNotebook(notebook);
  195. }
  196. }
  197. void VNotebookSelector::deleteNotebook(VNotebook *p_notebook)
  198. {
  199. int idx = indexOfNotebook(p_notebook);
  200. m_notebooks.remove(idx);
  201. vconfig.setNotebooks(m_notebooks);
  202. removeNotebookItem(idx);
  203. VNotebook::deleteNotebook(p_notebook);
  204. }
  205. int VNotebookSelector::indexOfNotebook(const VNotebook *p_notebook)
  206. {
  207. for (int i = 0; i < m_notebooks.size(); ++i) {
  208. if (m_notebooks[i] == p_notebook) {
  209. return i;
  210. }
  211. }
  212. return -1;
  213. }
  214. void VNotebookSelector::editNotebookInfo()
  215. {
  216. QList<QListWidgetItem *> items = m_listWidget->selectedItems();
  217. if (items.isEmpty()) {
  218. return;
  219. }
  220. Q_ASSERT(items.size() == 1);
  221. QListWidgetItem *item = items[0];
  222. int index = indexOfListItem(item);
  223. VNotebook *notebook = getNotebookFromComboIndex(index);
  224. QString info;
  225. QString curName = notebook->getName();
  226. QString defaultPath = notebook->getPath();
  227. QString defaultName(curName);
  228. do {
  229. VNotebookInfoDialog dialog(tr("Notebook Information"), info, defaultName,
  230. defaultPath, this);
  231. if (dialog.exec() == QDialog::Accepted) {
  232. QString name = dialog.getNameInput();
  233. if (name == curName) {
  234. return;
  235. }
  236. if (findNotebook(name)) {
  237. info = "Name already exists. Please choose another name.";
  238. defaultName = name;
  239. continue;
  240. }
  241. notebook->rename(name);
  242. updateComboBoxItem(index, name);
  243. vconfig.setNotebooks(m_notebooks);
  244. emit notebookUpdated(notebook);
  245. }
  246. break;
  247. } while (true);
  248. }
  249. void VNotebookSelector::addNotebookItem(const QString &p_name)
  250. {
  251. QListWidgetItem *item = new QListWidgetItem(m_listWidget);
  252. item->setText(p_name);
  253. item->setToolTip(p_name);
  254. item->setIcon(QIcon(":/resources/icons/notebook_item.svg"));
  255. }
  256. void VNotebookSelector::removeNotebookItem(int p_index)
  257. {
  258. QListWidgetItem *item = m_listWidget->item(p_index + c_notebookStartIdx);
  259. m_listWidget->removeItemWidget(item);
  260. delete item;
  261. }
  262. void VNotebookSelector::updateComboBoxItem(int p_index, const QString &p_name)
  263. {
  264. QListWidgetItem *item = m_listWidget->item(p_index);
  265. item->setText(p_name);
  266. item->setToolTip(p_name);
  267. }
  268. void VNotebookSelector::requestPopupListContextMenu(QPoint p_pos)
  269. {
  270. QModelIndex index = m_listWidget->indexAt(p_pos);
  271. if (!index.isValid() || index.row() < c_notebookStartIdx) {
  272. return;
  273. }
  274. QListWidgetItem *item = m_listWidget->itemAt(p_pos);
  275. Q_ASSERT(item);
  276. m_listWidget->clearSelection();
  277. item->setSelected(true);
  278. QMenu menu(this);
  279. menu.addAction(m_deleteNotebookAct);
  280. menu.addAction(m_notebookInfoAct);
  281. menu.exec(m_listWidget->mapToGlobal(p_pos));
  282. }
  283. bool VNotebookSelector::eventFilter(QObject *watched, QEvent *event)
  284. {
  285. if (event->type() == QEvent::MouseButtonRelease) {
  286. if (static_cast<QMouseEvent *>(event)->button() == Qt::RightButton) {
  287. return true;
  288. }
  289. }
  290. return QComboBox::eventFilter(watched, event);
  291. }
  292. int VNotebookSelector::indexOfListItem(const QListWidgetItem *p_item)
  293. {
  294. int nrItems = m_listWidget->count();
  295. for (int i = 0; i < nrItems; ++i) {
  296. if (m_listWidget->item(i) == p_item) {
  297. return i;
  298. }
  299. }
  300. return -1;
  301. }
  302. bool VNotebookSelector::locateNotebook(const VNotebook *p_notebook)
  303. {
  304. if (p_notebook) {
  305. for (int i = 0; i < m_notebooks.size(); ++i) {
  306. if (m_notebooks[i] == p_notebook) {
  307. setCurrentIndexNotebook(i);
  308. return true;
  309. }
  310. }
  311. }
  312. return false;
  313. }
  314. void VNotebookSelector::showPopup()
  315. {
  316. if (count() <= c_notebookStartIdx) {
  317. // No normal notebook items. Just add notebook.
  318. newNotebook();
  319. return;
  320. }
  321. QComboBox::showPopup();
  322. }