#include "vlistwidget.h" #include #include #include #include #include "utils/vutils.h" #include "utils/vimnavigationforwidget.h" #include "vstyleditemdelegate.h" VListWidget::VListWidget(QWidget *p_parent) : QListWidget(p_parent), ISimpleSearch(), m_fitContent(false) { m_searchInput = new VSimpleSearchInput(this, this); connect(m_searchInput, &VSimpleSearchInput::triggered, this, &VListWidget::handleSearchModeTriggered); m_searchInput->hide(); m_delegate = new VStyledItemDelegate(this); setItemDelegate(m_delegate); } void VListWidget::keyPressEvent(QKeyEvent *p_event) { if (m_searchInput->tryHandleKeyPressEvent(p_event)) { return; } if (VimNavigationForWidget::injectKeyPressEventForVim(this, p_event)) { return; } QListWidget::keyPressEvent(p_event); } void VListWidget::clearAll() { m_searchInput->clear(); setSearchInputVisible(false); QListWidget::clear(); } void VListWidget::setSearchInputVisible(bool p_visible) { m_searchInput->setVisible(p_visible); int bottomMargin = 0; if (p_visible) { bottomMargin = m_searchInput->height(); } setViewportMargins(0, 0, 0, bottomMargin); } void VListWidget::resizeEvent(QResizeEvent *p_event) { QListWidget::resizeEvent(p_event); QRect rect = contentsRect(); int width = rect.width(); QScrollBar *vbar = verticalScrollBar(); if (vbar && (vbar->minimum() != vbar->maximum())) { width -= vbar->width(); } int y = rect.bottom() - m_searchInput->height(); QScrollBar *hbar = horizontalScrollBar(); if (hbar && (hbar->minimum() != hbar->maximum())) { y -= hbar->height(); } m_searchInput->setGeometry(QRect(rect.left(), y, width, m_searchInput->height())); } void VListWidget::handleSearchModeTriggered(bool p_inSearchMode, bool p_focus) { setSearchInputVisible(p_inSearchMode); if (!p_inSearchMode) { clearItemsHighlight(); } if (p_focus) { setFocus(); } } QList VListWidget::searchItems(const QString &p_text, Qt::MatchFlags p_flags) const { QList items = findItems(p_text, p_flags); QList res; res.reserve(items.size()); for (int i = 0; i < items.size(); ++i) { res.append(items[i]); } return res; } void VListWidget::highlightHitItems(const QList &p_items) { clearItemsHighlight(); QSet hitIndexes; for (auto it : p_items) { QModelIndex index = indexFromItem(static_cast(it)); if (index.isValid()) { hitIndexes.insert(index); } } if (!hitIndexes.isEmpty()) { m_delegate->setHitItems(hitIndexes); update(); } } void VListWidget::clearItemsHighlight() { m_delegate->clearHitItems(); update(); } void VListWidget::selectHitItem(void *p_item) { setCurrentItem(static_cast(p_item), QItemSelectionModel::ClearAndSelect); } int VListWidget::totalNumberOfItems() { return count(); } void VListWidget::selectNextItem(bool p_forward) { if (count() == 0) { return; } int cur = currentRow(); cur = cur + (p_forward ? 1 : -1); if (cur < 0) { cur = 0; } else if (cur >= count()) { cur = count() - 1; } setCurrentRow(cur); } void VListWidget::sortListWidget(QListWidget *p_list, const QVector &p_sortedIdx) { int cnt = p_list->count(); Q_ASSERT(cnt == p_sortedIdx.size()); QVector sortedItems(cnt); for (int i = 0; i < cnt; ++i) { sortedItems[i] = p_list->item(p_sortedIdx[i]); } for (int i = 0; i < cnt; ++i) { QListWidgetItem *it = p_list->takeItem(p_list->row(sortedItems[i])); p_list->insertItem(i, it); } } QSize VListWidget::sizeHint() const { int cnt = count(); if (cnt == 0 || !m_fitContent) { return QListWidget::sizeHint(); } else { // Adjust size to content. int hei = 0; int wid = sizeHintForColumn(0) + 10; for (int i = 0; i < cnt; ++i) { hei += sizeHintForRow(i); } hei += 2 * cnt; // Scrollbar. QScrollBar *verBar = verticalScrollBar(); QScrollBar *horBar = horizontalScrollBar(); if (verBar && (verBar->minimum() != verBar->maximum())) { wid += verBar->width(); } if (horBar && (horBar->minimum() != horBar->maximum())) { hei += horBar->height(); } return QSize(wid, hei); } }