#include "notebookselector.h" #include #include #include #include #include #include #include #include #include #include #include using namespace vnotex; NotebookSelector::NotebookSelector(QWidget *p_parent) : ComboBox(p_parent), NavigationMode(NavigationMode::Type::StagedDoubleKeys, this) { auto itemDelegate = new QStyledItemDelegate(this); setItemDelegate(itemDelegate); view()->installEventFilter(this); setSizeAdjustPolicy(QComboBox::AdjustToMinimumContentsLengthWithIcon); } void NotebookSelector::loadNotebooks() { clear(); auto ¬ebookMgr = VNoteX::getInst().getNotebookMgr(); auto notebooks = notebookMgr.getNotebooks(); sortNotebooks(notebooks); for (auto &nb : notebooks) { addNotebookItem(nb); } updateGeometry(); m_notebooksInitialized = true; } void NotebookSelector::sortNotebooks(QVector> &p_notebooks) const { bool reversed = false; switch (m_viewOrder) { case ViewOrder::OrderedByNameReversed: reversed = true; Q_FALLTHROUGH(); case ViewOrder::OrderedByName: std::sort(p_notebooks.begin(), p_notebooks.end(), [reversed](const QSharedPointer &p_a, const QSharedPointer &p_b) { if (reversed) { return p_b->getName().toLower() < p_a->getName().toLower(); } else { return p_a->getName().toLower() < p_b->getName().toLower(); } }); break; case ViewOrder::OrderedByCreatedTimeReversed: reversed = true; Q_FALLTHROUGH(); case ViewOrder::OrderedByCreatedTime: std::sort(p_notebooks.begin(), p_notebooks.end(), [reversed](const QSharedPointer &p_a, const QSharedPointer &p_b) { if (reversed) { return p_b->getCreatedTimeUtc() < p_a->getCreatedTimeUtc(); } else { return p_a->getCreatedTimeUtc() < p_b->getCreatedTimeUtc(); } }); break; default: break; } } void NotebookSelector::reloadNotebook(const Notebook *p_notebook) { Q_ASSERT(p_notebook); int idx = findNotebook(p_notebook->getId()); Q_ASSERT(idx != -1); setItemIcon(idx, generateItemIcon(p_notebook)); setItemText(idx, p_notebook->getName()); setItemToolTip(idx, generateItemToolTip(p_notebook)); int curIdx = currentIndex(); if (curIdx == idx) { setToolTip(getItemToolTip(idx)); } } void NotebookSelector::addNotebookItem(const QSharedPointer &p_notebook) { int idx = count(); addItem(generateItemIcon(p_notebook.data()), p_notebook->getName(), p_notebook->getId()); setItemToolTip(idx, generateItemToolTip(p_notebook.data())); } void NotebookSelector::fetchIconColor(const QString &p_name, QString &p_fg, QString &p_bg) { static QVector backgroundColors = { "#80558c", "#df7861", "#f65a83", "#3b9ae1", "#277bc0", "#42855b", "#a62349", "#a66cff", "#9c9efe", "#54bab9", "#79b4b7", "#57cc99", "#916bbf", "#5c7aea", "#6867ac", }; int hashVal = 0; for (int i = 0; i < p_name.size(); ++i) { hashVal += p_name[i].unicode(); } p_fg = "#ffffff"; p_bg = backgroundColors[hashVal % backgroundColors.size()]; } QIcon NotebookSelector::generateItemIcon(const Notebook *p_notebook) { if (!p_notebook->getIcon().isNull()) { return p_notebook->getIcon(); } QString fg, bg; fetchIconColor(p_notebook->getName(), fg, bg); return IconUtils::drawTextRectIcon(p_notebook->getName().at(0).toUpper(), fg, bg, "", 50, 58); } QString NotebookSelector::generateItemToolTip(const Notebook *p_notebook) { return tr("Notebook: %1\nRoot folder: %2\nDescription: %3") .arg(p_notebook->getName(), p_notebook->getRootFolderAbsolutePath(), p_notebook->getDescription()); } QString NotebookSelector::getItemToolTip(int p_idx) const { return itemData(p_idx, Qt::ToolTipRole).toString(); } void NotebookSelector::setItemToolTip(int p_idx, const QString &p_tooltip) { setItemData(p_idx, p_tooltip, Qt::ToolTipRole); } void NotebookSelector::setCurrentNotebook(ID p_id) { int idx = findNotebook(p_id); setCurrentIndex(idx); setToolTip(getItemToolTip(idx)); } int NotebookSelector::findNotebook(ID p_id) const { return findData(p_id); } QVector NotebookSelector::getVisibleNavigationItems() { QVector items; auto listView = dynamic_cast(view()); if (listView) { m_navigationIndexes = WidgetUtils::getVisibleIndexes(listView); for (auto &index : m_navigationIndexes) { items.push_back(&index); } } return items; } void NotebookSelector::placeNavigationLabel(int p_idx, void *p_item, QLabel *p_label) { if (p_idx == -1) { // Major. p_label->move(rect().topRight() - QPoint(p_label->width() + 2, 2)); } else { // Second. // Reparent it to the list view. auto listView = view(); p_label->setParent(listView); auto index = *static_cast(p_item); int extraWidth = p_label->width() + 2; auto vbar = listView->verticalScrollBar(); if (vbar && vbar->minimum() != vbar->maximum()) { extraWidth += vbar->width(); } const auto rt = listView->visualRect(index); const int x = rt.x() + view()->width() - extraWidth; const int y = rt.y(); p_label->move(x, y); } } void NotebookSelector::handleTargetHit(void *p_item) { if (!p_item) { setFocus(); showPopup(); } else { hidePopup(); auto index = *static_cast(p_item); setCurrentIndex(index.row()); emit activated(index.row()); } } bool NotebookSelector::eventFilter(QObject *p_obj, QEvent *p_event) { if (p_event->type() == QEvent::KeyPress && p_obj == view()) { if (WidgetUtils::processKeyEventLikeVi(view(), static_cast(p_event))) { return true; } } return ComboBox::eventFilter(p_obj, p_event); } void NotebookSelector::clearNavigation() { m_navigationIndexes.clear(); NavigationMode::clearNavigation(); } void NotebookSelector::mousePressEvent(QMouseEvent *p_event) { // Only when notebooks are loaded and there is no notebook, we could prompt for new notebook. if (m_notebooksInitialized && count() == 0) { emit newNotebookRequested(); return; } ComboBox::mousePressEvent(p_event); } void NotebookSelector::setViewOrder(int p_order) { if (m_viewOrder == p_order) { return; } if (p_order >= 0 && p_order < ViewOrder::ViewOrderMax) { m_viewOrder = static_cast(p_order); loadNotebooks(); } }