diff --git a/src/isearchengine.h b/src/isearchengine.h index 3ccb4c82..2d511efe 100644 --- a/src/isearchengine.h +++ b/src/isearchengine.h @@ -3,6 +3,7 @@ #include #include +#include #include "vsearchconfig.h" @@ -16,6 +17,11 @@ public: { } + virtual ~ISearchEngine() + { + m_result.clear(); + } + virtual void search(const QSharedPointer &p_config, const QSharedPointer &p_result) = 0; @@ -26,7 +32,7 @@ public: signals: void finished(const QSharedPointer &p_result); - void resultItemAdded(const QSharedPointer &p_item); + void resultItemsAdded(const QList > &p_items); protected: QSharedPointer m_result; diff --git a/src/vlineedit.cpp b/src/vlineedit.cpp index 79f43091..06a6ce21 100644 --- a/src/vlineedit.cpp +++ b/src/vlineedit.cpp @@ -5,12 +5,16 @@ #include "utils/vutils.h" VLineEdit::VLineEdit(QWidget *p_parent) - : QLineEdit(p_parent), m_ctrlKEnabled(true) + : QLineEdit(p_parent), + m_ctrlKEnabled(true), + m_ctrlEEnabled(true) { } VLineEdit::VLineEdit(const QString &p_contents, QWidget *p_parent) - : QLineEdit(p_contents, p_parent), m_ctrlKEnabled(true) + : QLineEdit(p_contents, p_parent), + m_ctrlKEnabled(true), + m_ctrlEEnabled(true) { } @@ -74,6 +78,16 @@ void VLineEdit::keyPressEvent(QKeyEvent *p_event) break; } + case Qt::Key_E: + { + if (VUtils::isControlModifierForVim(modifiers) && !m_ctrlEEnabled) { + QWidget::keyPressEvent(p_event); + accept = true; + } + + break; + } + default: break; } diff --git a/src/vlineedit.h b/src/vlineedit.h index dc7349a8..d9ef52a4 100644 --- a/src/vlineedit.h +++ b/src/vlineedit.h @@ -14,6 +14,8 @@ public: void setCtrlKEnabled(bool p_enabled); + void setCtrlEEnabled(bool p_enabled); + protected: void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; @@ -21,6 +23,10 @@ private: // Enable Ctrl+K shortcut. // In QLineEdit, Ctrl+K will delete till the end. bool m_ctrlKEnabled; + + // Enable Ctrl+E shortcut. + // In QLineEdit, Ctrl+E will move the cursor to the end. + bool m_ctrlEEnabled; }; inline void VLineEdit::setCtrlKEnabled(bool p_enabled) @@ -28,4 +34,8 @@ inline void VLineEdit::setCtrlKEnabled(bool p_enabled) m_ctrlKEnabled = p_enabled; } +inline void VLineEdit::setCtrlEEnabled(bool p_enabled) +{ + m_ctrlEEnabled = p_enabled; +} #endif // VLINEEDIT_H diff --git a/src/vsearch.cpp b/src/vsearch.cpp index f97aeb69..9dc18deb 100644 --- a/src/vsearch.cpp +++ b/src/vsearch.cpp @@ -442,8 +442,8 @@ void VSearch::searchSecondPhase(const QSharedPointer &p_result) if (m_engine) { connect(m_engine, &ISearchEngine::finished, this, &VSearch::finished); - connect(m_engine, &ISearchEngine::resultItemAdded, - this, &VSearch::resultItemAdded); + connect(m_engine, &ISearchEngine::resultItemsAdded, + this, &VSearch::resultItemsAdded); } } diff --git a/src/vsearch.h b/src/vsearch.h index bd9021d6..fafed4a4 100644 --- a/src/vsearch.h +++ b/src/vsearch.h @@ -41,6 +41,8 @@ signals: // Emitted when a new item added as result. void resultItemAdded(const QSharedPointer &p_item); + void resultItemsAdded(const QList > &p_items); + // Emitted when async task finished. void finished(const QSharedPointer &p_result); diff --git a/src/vsearchengine.cpp b/src/vsearchengine.cpp index f5e25e01..c771dd0e 100644 --- a/src/vsearchengine.cpp +++ b/src/vsearchengine.cpp @@ -32,6 +32,8 @@ void VSearchEngineWorker::run() QMimeDatabase mimeDatabase; m_state = VSearchState::Busy; + m_results.clear(); + int nr = 0; for (auto const & fileName : m_files) { if (m_stop.load() == 1) { m_state = VSearchState::Cancelled; @@ -47,10 +49,17 @@ void VSearchEngineWorker::run() VSearchResultItem *item = searchFile(fileName); if (item) { - emit resultItemReady(item); + m_results.append(QSharedPointer(item)); + } + + if (++nr >= BATCH_ITEM_SIZE) { + nr = 0; + postAndClearResults(); } } + postAndClearResults(); + if (m_state == VSearchState::Busy) { m_state = VSearchState::Success; } @@ -122,6 +131,14 @@ VSearchResultItem *VSearchEngineWorker::searchFile(const QString &p_fileName) return item; } +void VSearchEngineWorker::postAndClearResults() +{ + if (!m_results.isEmpty()) { + emit resultItemsReady(m_results); + m_results.clear(); + } +} + VSearchEngine::VSearchEngine(QObject *p_parent) : ISearchEngine(p_parent), @@ -129,6 +146,12 @@ VSearchEngine::VSearchEngine(QObject *p_parent) { } +VSearchEngine::~VSearchEngine() +{ + stop(); + clear(); +} + void VSearchEngine::search(const QSharedPointer &p_config, const QSharedPointer &p_result) { @@ -168,9 +191,9 @@ void VSearchEngine::search(const QSharedPointer &p_config, p_config->m_contentToken); connect(th, &VSearchEngineWorker::finished, this, &VSearchEngine::handleWorkerFinished); - connect(th, &VSearchEngineWorker::resultItemReady, - this, [this](VSearchResultItem *p_item) { - emit resultItemAdded(QSharedPointer(p_item)); + connect(th, &VSearchEngineWorker::resultItemsReady, + this, [this](const QList > &p_items) { + emit resultItemsAdded(p_items); }); m_workers.append(th); diff --git a/src/vsearchengine.h b/src/vsearchengine.h index ac7c57b4..8fda5a6f 100644 --- a/src/vsearchengine.h +++ b/src/vsearchengine.h @@ -6,9 +6,12 @@ #include #include #include +#include #include "vsearchconfig.h" +#define BATCH_ITEM_SIZE 100 + class VSearchEngineWorker : public QThread { Q_OBJECT @@ -25,7 +28,7 @@ public slots: void stop(); signals: - void resultItemReady(VSearchResultItem *p_item); + void resultItemsReady(const QList > &p_items); protected: void run() Q_DECL_OVERRIDE; @@ -35,6 +38,8 @@ private: VSearchResultItem *searchFile(const QString &p_fileName); + void postAndClearResults(); + QAtomicInt m_stop; QStringList m_files; @@ -44,6 +49,8 @@ private: VSearchState m_state; QString m_error; + + QList > m_results; }; inline void VSearchEngineWorker::appendError(const QString &p_err) @@ -62,6 +69,8 @@ class VSearchEngine : public ISearchEngine public: explicit VSearchEngine(QObject *p_parent = nullptr); + ~VSearchEngine(); + void search(const QSharedPointer &p_config, const QSharedPointer &p_result) Q_DECL_OVERRIDE; diff --git a/src/vsearcher.cpp b/src/vsearcher.cpp index 8e671d08..875f70e3 100644 --- a/src/vsearcher.cpp +++ b/src/vsearcher.cpp @@ -29,6 +29,8 @@ VSearcher::VSearcher(QWidget *p_parent) m_askedToStop(false), m_search(this) { + qRegisterMetaType>>("QList>"); + setupUI(); initUIFields(); @@ -36,7 +38,17 @@ VSearcher::VSearcher(QWidget *p_parent) handleInputChanged(); connect(&m_search, &VSearch::resultItemAdded, - m_results, &VSearchResultTree::addResultItem); + this, [this](const QSharedPointer &p_item) { + // Not sure if it works. + QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease); + m_results->addResultItem(p_item); + }); + connect(&m_search, &VSearch::resultItemsAdded, + this, [this](const QList > &p_items) { + // Not sure if it works. + QCoreApplication::sendPostedEvents(NULL, QEvent::MouseButtonRelease); + m_results->addResultItems(p_items); + }); connect(&m_search, &VSearch::finished, this, &VSearcher::handleSearchFinished); } @@ -352,6 +364,8 @@ void VSearcher::startSearch() updateItemToComboBox(m_keywordCB); updateItemToComboBox(m_filePatternCB); + m_search.clear(); + QSharedPointer config(new VSearchConfig(m_searchScopeCB->currentData().toInt(), m_searchObjectCB->currentData().toInt(), m_searchTargetCB->currentData().toInt(), diff --git a/src/vsearchresulttree.cpp b/src/vsearchresulttree.cpp index ddc4f25e..6c29a2e6 100644 --- a/src/vsearchresulttree.cpp +++ b/src/vsearchresulttree.cpp @@ -78,6 +78,15 @@ void VSearchResultTree::addResultItem(const QSharedPointer &p 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(); diff --git a/src/vsearchresulttree.h b/src/vsearchresulttree.h index 253b8cfd..154caaae 100644 --- a/src/vsearchresulttree.h +++ b/src/vsearchresulttree.h @@ -22,6 +22,8 @@ public: public slots: void addResultItem(const QSharedPointer &p_item); + void addResultItems(const QList > &p_items); + void handleContextMenuRequested(QPoint p_pos); signals: diff --git a/src/vsearchue.cpp b/src/vsearchue.cpp index 1a452af9..c58718d9 100644 --- a/src/vsearchue.cpp +++ b/src/vsearchue.cpp @@ -18,6 +18,8 @@ extern VNote *g_vnote; extern VMainWindow *g_mainWin; +#define ITEM_NUM_TO_UPDATE_WIDGET 20 + VSearchUE::VSearchUE(QObject *p_parent) : IUniversalEntry(p_parent), m_search(NULL), @@ -59,6 +61,8 @@ void VSearchUE::init() m_search = new VSearch(this); connect(m_search, &VSearch::resultItemAdded, this, &VSearchUE::handleSearchItemAdded); + connect(m_search, &VSearch::resultItemsAdded, + this, &VSearchUE::handleSearchItemsAdded); connect(m_search, &VSearch::finished, this, &VSearchUE::handleSearchFinished); @@ -132,7 +136,23 @@ void VSearchUE::processCommand(int p_id, const QString &p_cmd) break; } - widget(p_id)->updateGeometry(); + updateWidget(); +} + +void VSearchUE::updateWidget() +{ + QWidget *wid = widget(m_id); + if (wid == m_treeWidget) { + if (m_treeWidget->topLevelItemCount() > 0) { + m_treeWidget->resizeColumnToContents(0); + } else { + QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget, QStringList("test")); + m_treeWidget->resizeColumnToContents(0); + delete item; + } + } + + wid->updateGeometry(); emit widgetUpdated(); } @@ -153,6 +173,7 @@ void VSearchUE::searchNameOfAllNotebooks(const QString &p_cmd) emit stateUpdated(State::Success); } else { // Do a fuzzy search against the name of the notebooks. + m_search->clear(); VSearchConfig::Option opt = VSearchConfig::Fuzzy; QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, VSearchConfig::Name, @@ -175,6 +196,7 @@ void VSearchUE::searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd) m_inSearch = false; emit stateUpdated(State::Success); } else { + m_search->clear(); VSearchConfig::Option opt = VSearchConfig::NoneOption; QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, VSearchConfig::Name, @@ -196,6 +218,7 @@ void VSearchUE::searchContentOfNoteInAllNotebooks(const QString &p_cmd) m_inSearch = false; emit stateUpdated(State::Success); } else { + m_search->clear(); VSearchConfig::Option opt = VSearchConfig::NoneOption; QSharedPointer config(new VSearchConfig(VSearchConfig::AllNotebooks, VSearchConfig::Content, @@ -227,14 +250,32 @@ void VSearchUE::entryHidden(int p_id) void VSearchUE::handleSearchItemAdded(const QSharedPointer &p_item) { + static int itemAdded = 0; + ++itemAdded; + + QCoreApplication::sendPostedEvents(NULL, QEvent::KeyPress); + switch (m_id) { case ID::Name_Notebook_AllNotebook: case ID::Name_FolderNote_AllNotebook: appendItemToList(p_item); + if (itemAdded > 50) { + itemAdded = 0; + m_listWidget->updateGeometry(); + emit widgetUpdated(); + } + break; case ID::Content_Note_AllNotebook: appendItemToTree(p_item); + if (itemAdded > 50) { + itemAdded = 0; + m_treeWidget->resizeColumnToContents(0); + m_treeWidget->updateGeometry(); + emit widgetUpdated(); + } + break; default: @@ -242,9 +283,42 @@ void VSearchUE::handleSearchItemAdded(const QSharedPointer &p } } +void VSearchUE::handleSearchItemsAdded(const QList > &p_items) +{ + QCoreApplication::sendPostedEvents(NULL, QEvent::KeyPress); + + switch (m_id) { + case ID::Name_Notebook_AllNotebook: + case ID::Name_FolderNote_AllNotebook: + { + for (auto const & it : p_items) { + appendItemToList(it); + } + + m_listWidget->updateGeometry(); + emit widgetUpdated(); + break; + } + + case ID::Content_Note_AllNotebook: + { + for (auto const & it : p_items) { + appendItemToTree(it); + } + + m_treeWidget->resizeColumnToContents(0); + m_treeWidget->updateGeometry(); + emit widgetUpdated(); + break; + } + + default: + break; + } +} + void VSearchUE::appendItemToList(const QSharedPointer &p_item) { - static int itemAdded = 0; m_data.append(p_item); QString first, second; @@ -277,21 +351,13 @@ void VSearchUE::appendItemToList(const QSharedPointer &p_item item->setData(Qt::UserRole, m_data.size() - 1); item->setToolTip(p_item->m_path); - ++itemAdded; if (m_listWidget->currentRow() == -1) { m_listWidget->setCurrentRow(0); - m_listWidget->updateGeometry(); - emit widgetUpdated(); - } else if (itemAdded >= 20) { - itemAdded = 0; - m_listWidget->updateGeometry(); - emit widgetUpdated(); } } void VSearchUE::appendItemToTree(const QSharedPointer &p_item) { - static int itemAdded = 0; m_data.append(p_item); QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget); @@ -329,16 +395,8 @@ void VSearchUE::appendItemToTree(const QSharedPointer &p_item subItem->setToolTip(0, it.m_text); } - ++itemAdded; if (!m_treeWidget->currentItem()) { m_treeWidget->setCurrentItem(item); - m_treeWidget->resizeColumnToContents(0); - m_treeWidget->updateGeometry(); - emit widgetUpdated(); - } else if (itemAdded >= 20) { - itemAdded = 0; - m_treeWidget->updateGeometry(); - emit widgetUpdated(); } } @@ -383,13 +441,7 @@ void VSearchUE::handleSearchFinished(const QSharedPointer &p_resu m_inSearch = false; } - QWidget *wid = widget(m_id); - if (wid == m_treeWidget) { - m_treeWidget->resizeColumnToContents(0); - } - - wid->updateGeometry(); - emit widgetUpdated(); + updateWidget(); emit stateUpdated(state); } @@ -525,5 +577,7 @@ void VSearchUE::activate(int p_id) void VSearchUE::askToStop(int p_id) { Q_UNUSED(p_id); - m_search->stop(); + if (m_inSearch) { + m_search->stop(); + } } diff --git a/src/vsearchue.h b/src/vsearchue.h index ba859317..014f8833 100644 --- a/src/vsearchue.h +++ b/src/vsearchue.h @@ -55,6 +55,8 @@ protected: private slots: void handleSearchItemAdded(const QSharedPointer &p_item); + void handleSearchItemsAdded(const QList > &p_items); + void handleSearchFinished(const QSharedPointer &p_result); void activateItem(QListWidgetItem *p_item); @@ -81,6 +83,9 @@ private: const QSharedPointer &itemResultData(const QTreeWidgetItem *p_item) const; + // Update geometry of widget. + void updateWidget(); + VSearch *m_search; bool m_inSearch; diff --git a/src/vuniversalentry.cpp b/src/vuniversalentry.cpp index 7587d310..efe93ffa 100644 --- a/src/vuniversalentry.cpp +++ b/src/vuniversalentry.cpp @@ -102,6 +102,8 @@ void VUniversalEntry::setupUI() { m_cmdEdit = new VMetaWordLineEdit(this); m_cmdEdit->setPlaceholderText(tr("Welcome to Universal Entry")); + m_cmdEdit->setCtrlKEnabled(false); + m_cmdEdit->setCtrlEEnabled(false); connect(m_cmdEdit, &VMetaWordLineEdit::textEdited, this, [this]() { m_cmdTimer->stop(); @@ -136,6 +138,9 @@ void VUniversalEntry::showEvent(QShowEvent *p_event) { QWidget::showEvent(p_event); + // Fix Chinese input method issue. + activateWindow(); + m_cmdEdit->setFocus(); } @@ -297,6 +302,18 @@ void VUniversalEntry::keyPressEvent(QKeyEvent *p_event) break; + case Qt::Key_D: + if (VUtils::isControlModifierForVim(modifiers)) { + // Ctrl+D to cancel current command. + m_pendingCommand = false; + if (m_lastEntry) { + m_lastEntry->m_entry->askToStop(m_lastEntry->m_id); + } + return; + } + + break; + default: break; }