notebookselector.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. #include "notebookselector.h"
  2. #include <QKeyEvent>
  3. #include <QAbstractItemView>
  4. #include <QStyledItemDelegate>
  5. #include <QLabel>
  6. #include <QListView>
  7. #include <QScrollBar>
  8. #include "vnotex.h"
  9. #include "notebook/notebook.h"
  10. #include <utils/iconutils.h>
  11. #include <utils/widgetutils.h>
  12. using namespace vnotex;
  13. NotebookSelector::NotebookSelector(QWidget *p_parent)
  14. : ComboBox(p_parent),
  15. NavigationMode(NavigationMode::Type::StagedDoubleKeys, this)
  16. {
  17. auto itemDelegate = new QStyledItemDelegate(this);
  18. setItemDelegate(itemDelegate);
  19. view()->installEventFilter(this);
  20. setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon);
  21. }
  22. void NotebookSelector::setNotebooks(const QVector<QSharedPointer<Notebook>> &p_notebooks)
  23. {
  24. clear();
  25. for (auto &nb : p_notebooks) {
  26. addNotebookItem(nb);
  27. }
  28. updateGeometry();
  29. m_notebooksInitialized = true;
  30. }
  31. void NotebookSelector::reloadNotebook(const Notebook *p_notebook)
  32. {
  33. Q_ASSERT(p_notebook);
  34. int idx = findNotebook(p_notebook->getId());
  35. Q_ASSERT(idx != -1);
  36. setItemIcon(idx, generateItemIcon(p_notebook));
  37. setItemText(idx, p_notebook->getName());
  38. setItemToolTip(idx, generateItemToolTip(p_notebook));
  39. int curIdx = currentIndex();
  40. if (curIdx == idx) {
  41. setToolTip(getItemToolTip(idx));
  42. }
  43. }
  44. void NotebookSelector::addNotebookItem(const QSharedPointer<Notebook> &p_notebook)
  45. {
  46. int idx = count();
  47. addItem(generateItemIcon(p_notebook.data()), p_notebook->getName(), p_notebook->getId());
  48. setItemToolTip(idx, generateItemToolTip(p_notebook.data()));
  49. }
  50. void NotebookSelector::fetchIconColor(const QString &p_name, QString &p_fg, QString &p_bg)
  51. {
  52. static QVector<QString> backgroundColors = {
  53. "#80558c",
  54. "#df7861",
  55. "#f65a83",
  56. "#3b9ae1",
  57. "#277bc0",
  58. "#42855b",
  59. "#a62349",
  60. "#a66cff",
  61. "#9c9efe",
  62. "#54bab9",
  63. "#79b4b7",
  64. "#57cc99",
  65. "#916bbf",
  66. "#5c7aea",
  67. "#6867ac",
  68. };
  69. int hashVal = 0;
  70. for (int i = 0; i < p_name.size(); ++i) {
  71. hashVal += p_name[i].unicode();
  72. }
  73. p_fg = "#ffffff";
  74. p_bg = backgroundColors[hashVal % backgroundColors.size()];
  75. }
  76. QIcon NotebookSelector::generateItemIcon(const Notebook *p_notebook)
  77. {
  78. if (!p_notebook->getIcon().isNull()) {
  79. return p_notebook->getIcon();
  80. }
  81. QString fg, bg;
  82. fetchIconColor(p_notebook->getName(), fg, bg);
  83. return IconUtils::drawTextRectIcon(p_notebook->getName().at(0).toUpper(),
  84. fg,
  85. bg,
  86. "",
  87. 50,
  88. 58);
  89. }
  90. QString NotebookSelector::generateItemToolTip(const Notebook *p_notebook)
  91. {
  92. return tr("Notebook: %1\nRoot folder: %2\nDescription: %3")
  93. .arg(p_notebook->getName(),
  94. p_notebook->getRootFolderAbsolutePath(),
  95. p_notebook->getDescription());
  96. }
  97. QString NotebookSelector::getItemToolTip(int p_idx) const
  98. {
  99. return itemData(p_idx, Qt::ToolTipRole).toString();
  100. }
  101. void NotebookSelector::setItemToolTip(int p_idx, const QString &p_tooltip)
  102. {
  103. setItemData(p_idx, p_tooltip, Qt::ToolTipRole);
  104. }
  105. void NotebookSelector::setCurrentNotebook(ID p_id)
  106. {
  107. int idx = findNotebook(p_id);
  108. setCurrentIndex(idx);
  109. setToolTip(getItemToolTip(idx));
  110. }
  111. int NotebookSelector::findNotebook(ID p_id) const
  112. {
  113. return findData(p_id);
  114. }
  115. QVector<void *> NotebookSelector::getVisibleNavigationItems()
  116. {
  117. QVector<void *> items;
  118. auto listView = dynamic_cast<QListView *>(view());
  119. if (listView) {
  120. m_navigationIndexes = WidgetUtils::getVisibleIndexes(listView);
  121. for (auto &index : m_navigationIndexes) {
  122. items.push_back(&index);
  123. }
  124. }
  125. return items;
  126. }
  127. void NotebookSelector::placeNavigationLabel(int p_idx, void *p_item, QLabel *p_label)
  128. {
  129. if (p_idx == -1) {
  130. // Major.
  131. p_label->move(rect().topRight() - QPoint(p_label->width() + 2, 2));
  132. } else {
  133. // Second.
  134. // Reparent it to the list view.
  135. auto listView = view();
  136. p_label->setParent(listView);
  137. auto index = *static_cast<QModelIndex *>(p_item);
  138. int extraWidth = p_label->width() + 2;
  139. auto vbar = listView->verticalScrollBar();
  140. if (vbar && vbar->minimum() != vbar->maximum()) {
  141. extraWidth += vbar->width();
  142. }
  143. const auto rt = listView->visualRect(index);
  144. const int x = rt.x() + view()->width() - extraWidth;
  145. const int y = rt.y();
  146. p_label->move(x, y);
  147. }
  148. }
  149. void NotebookSelector::handleTargetHit(void *p_item)
  150. {
  151. if (!p_item) {
  152. setFocus();
  153. showPopup();
  154. } else {
  155. hidePopup();
  156. auto index = *static_cast<QModelIndex *>(p_item);
  157. setCurrentIndex(index.row());
  158. emit activated(index.row());
  159. }
  160. }
  161. bool NotebookSelector::eventFilter(QObject *p_obj, QEvent *p_event)
  162. {
  163. if (p_event->type() == QEvent::KeyPress && p_obj == view()) {
  164. if (WidgetUtils::processKeyEventLikeVi(view(), static_cast<QKeyEvent *>(p_event))) {
  165. return true;
  166. }
  167. }
  168. return ComboBox::eventFilter(p_obj, p_event);
  169. }
  170. void NotebookSelector::clearNavigation()
  171. {
  172. m_navigationIndexes.clear();
  173. NavigationMode::clearNavigation();
  174. }
  175. void NotebookSelector::mousePressEvent(QMouseEvent *p_event)
  176. {
  177. // Only when notebooks are loaded and there is no notebook, we could prompt for new notebook.
  178. if (m_notebooksInitialized && count() == 0) {
  179. emit newNotebookRequested();
  180. return;
  181. }
  182. ComboBox::mousePressEvent(p_event);
  183. }