#include "vsearchresulttree.h" #include #include #include "utils/vutils.h" #include "utils/viconutils.h" #include "vnote.h" #include "vmainwindow.h" #include "vnotefile.h" #include "vcart.h" #include "vhistorylist.h" #include "vexplorer.h" #include "vuniversalentry.h" #include "vsearchue.h" #include "vconstants.h" extern VNote *g_vnote; extern VMainWindow *g_mainWin; VSearchResultTree::VSearchResultTree(QWidget *p_parent) : VTreeWidget(p_parent) { setColumnCount(1); setHeaderHidden(true); setExpandsOnDoubleClick(false); setContextMenuPolicy(Qt::CustomContextMenu); setSelectionMode(QAbstractItemView::ExtendedSelection); setSimpleSearchMatchFlags(getSimpleSearchMatchFlags() & ~Qt::MatchRecursive); m_noteIcon = VIconUtils::treeViewIcon(":/resources/icons/note_item.svg"); m_folderIcon = VIconUtils::treeViewIcon(":/resources/icons/dir_item.svg"); m_notebookIcon = VIconUtils::treeViewIcon(":/resources/icons/notebook_item.svg"); connect(this, &VTreeWidget::itemActivated, this, &VSearchResultTree::activateItem); connect(this, &VTreeWidget::customContextMenuRequested, this, &VSearchResultTree::handleContextMenuRequested); } void VSearchResultTree::updateResults(const QList > &p_items) { clearResults(); for (auto const & it : p_items) { appendItem(it); } emit countChanged(topLevelItemCount()); } void VSearchResultTree::addResultItem(const QSharedPointer &p_item) { appendItem(p_item); emit countChanged(topLevelItemCount()); } void VSearchResultTree::addResultItems(const QList > &p_items) { for (auto const & it : p_items) { appendItem(it); } emit countChanged(topLevelItemCount()); } void VSearchResultTree::clearResults() { clearAll(); m_data.clear(); emit countChanged(topLevelItemCount()); } void VSearchResultTree::appendItem(const QSharedPointer &p_item) { m_data.append(p_item); QTreeWidgetItem *item = new QTreeWidgetItem(this); item->setData(0, Qt::UserRole, m_data.size() - 1); QString text; if (p_item->m_text.isEmpty()) { text = p_item->m_path; } else if (p_item->m_type != VSearchResultItem::Notebook) { text = VUniversalEntry::fileNameWithDir(p_item->m_text, p_item->m_path); } else { text = p_item->m_text; } item->setText(0, text); item->setToolTip(0, p_item->m_path); switch (p_item->m_type) { case VSearchResultItem::Note: item->setIcon(0, m_noteIcon); break; case VSearchResultItem::Folder: item->setIcon(0, m_folderIcon); break; case VSearchResultItem::Notebook: item->setIcon(0, m_notebookIcon); break; default: break; } for (auto const & it: p_item->m_matches) { QTreeWidgetItem *subItem = new QTreeWidgetItem(item); QString text; if (it.m_lineNumber > -1) { text = QString("[%1] %2").arg(it.m_lineNumber).arg(it.m_text); } else { text = it.m_text; } subItem->setText(0, text); subItem->setToolTip(0, it.m_text); } } void VSearchResultTree::handleContextMenuRequested(QPoint p_pos) { QMenu menu(this); menu.setToolTipsVisible(true); QTreeWidgetItem *item = itemAt(p_pos); if (!item) { goto global; } { QList items = selectedItems(); bool hasNote = false; for (auto const & it : items) { if (itemResultType(it) == VSearchResultItem::Note) { hasNote = true; break; } } if (items.size() == 1) { QAction *openAct = new QAction(tr("&Open"), &menu); openAct->setToolTip(tr("Open selected notes")); connect(openAct, &QAction::triggered, this, [this]() { activateItem(currentItem()); }); menu.addAction(openAct); if (hasNote) { QAction *locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"), tr("&Locate To Folder"), &menu); locateAct->setToolTip(tr("Locate the folder of current note")); connect(locateAct, &QAction::triggered, this, &VSearchResultTree::locateCurrentItem); menu.addAction(locateAct); } } if (hasNote) { QAction *addToCartAct = new QAction(VIconUtils::menuIcon(":/resources/icons/cart.svg"), tr("Add To Cart"), &menu); addToCartAct->setToolTip(tr("Add selected notes to Cart for further processing")); connect(addToCartAct, &QAction::triggered, this, &VSearchResultTree::addSelectedItemsToCart); menu.addAction(addToCartAct); QAction *pinToHistoryAct = new QAction(VIconUtils::menuIcon(":/resources/icons/pin.svg"), tr("Pin To History"), &menu); pinToHistoryAct->setToolTip(tr("Pin selected notes to History")); connect(pinToHistoryAct, &QAction::triggered, this, &VSearchResultTree::pinSelectedItemsToHistory); menu.addAction(pinToHistoryAct); } } global: if (topLevelItemCount() > 0) { if (item) { menu.addSeparator(); } QString shortcutText = VUtils::getShortcutText(Shortcut::c_expand); QAction *expandAct = new QAction(tr("Expand/Collapse All\t%1").arg(shortcutText), &menu); connect(expandAct, &QAction::triggered, this, &VSearchResultTree::expandCollapseAll); menu.addAction(expandAct); menu.exec(mapToGlobal(p_pos)); } } void VSearchResultTree::locateCurrentItem() { auto item = currentItem(); if (!item) { return; } const QSharedPointer &resItem = itemResultData(item); if (resItem->m_type == VSearchResultItem::Note) { VFile *file = g_vnote->getInternalFile(resItem->m_path); if (file) { g_mainWin->locateFile(file); } } } void VSearchResultTree::addSelectedItemsToCart() { QList items = selectedItems(); VCart *cart = g_mainWin->getCart(); int nrAdded = 0; for (int i = 0; i < items.size(); ++i) { const QSharedPointer &resItem = itemResultData(items[i]); if (resItem->m_type == VSearchResultItem::Note) { cart->addFile(resItem->m_path); ++nrAdded; } } if (nrAdded) { g_mainWin->showStatusMessage(tr("%1 %2 added to Cart") .arg(nrAdded) .arg(nrAdded > 1 ? tr("notes") : tr("note"))); } } void VSearchResultTree::pinSelectedItemsToHistory() { QList items = selectedItems(); QStringList files; for (int i = 0; i < items.size(); ++i) { const QSharedPointer &resItem = itemResultData(items[i]); if (resItem->m_type == VSearchResultItem::Note) { files << resItem->m_path; } } if (!files.isEmpty()) { g_mainWin->getHistoryList()->pinFiles(files); g_mainWin->showStatusMessage(tr("%1 %2 pinned to History") .arg(files.size()) .arg(files.size() > 1 ? tr("notes") : tr("note"))); } } VSearchResultItem::ItemType VSearchResultTree::itemResultType(const QTreeWidgetItem *p_item) const { Q_ASSERT(p_item); return itemResultData(p_item)->m_type; } const QSharedPointer &VSearchResultTree::itemResultData(const QTreeWidgetItem *p_item) const { Q_ASSERT(p_item); const QTreeWidgetItem *topItem = VTreeWidget::topLevelTreeItem(p_item); int idx = topItem->data(0, Qt::UserRole).toInt(); Q_ASSERT(idx >= 0 && idx < m_data.size()); return m_data[idx]; } void VSearchResultTree::activateItem(const QTreeWidgetItem *p_item) const { if (!p_item) { return; } VSearchUE::activateItem(itemResultData(p_item), VTreeWidget::childIndexOfTreeItem(p_item)); } void VSearchResultTree::expandCollapseAll() { VTreeWidget::expandCollapseAll(this); }