mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 22:09:52 +08:00
1258 lines
41 KiB
C++
1258 lines
41 KiB
C++
#include "vsearchue.h"
|
|
|
|
#include <QDebug>
|
|
#include <QVector>
|
|
|
|
#include "vlistwidgetdoublerows.h"
|
|
#include "vtreewidget.h"
|
|
#include "vnotebook.h"
|
|
#include "vnote.h"
|
|
#include "vsearch.h"
|
|
#include "utils/viconutils.h"
|
|
#include "utils/vutils.h"
|
|
#include "vmainwindow.h"
|
|
#include "vnotebookselector.h"
|
|
#include "vnotefile.h"
|
|
#include "vdirectory.h"
|
|
#include "vdirectorytree.h"
|
|
#include "veditarea.h"
|
|
#include "vexplorer.h"
|
|
#include "vuniversalentry.h"
|
|
#include "vconfigmanager.h"
|
|
|
|
extern VNote *g_vnote;
|
|
|
|
extern VMainWindow *g_mainWin;
|
|
|
|
extern VConfigManager *g_config;
|
|
|
|
#define ITEM_NUM_TO_UPDATE_WIDGET 20
|
|
|
|
VSearchUE::VSearchUE(QObject *p_parent)
|
|
: IUniversalEntry(p_parent),
|
|
m_search(NULL),
|
|
m_inSearch(false),
|
|
m_id(ID::Name_Notebook_AllNotebook),
|
|
m_listWidget(NULL),
|
|
m_treeWidget(NULL)
|
|
{
|
|
}
|
|
|
|
QString VSearchUE::description(int p_id) const
|
|
{
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
return tr("List and search all the notebooks");
|
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
return tr("Search the name of folders/notes in all the notebooks");
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
return tr("Search the content of notes in all the notebooks");
|
|
|
|
case ID::Tag_Note_AllNotebook:
|
|
return tr("Search the tags of notes in all the notebooks");
|
|
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
return tr("Search the name of folders/notes in current notebook");
|
|
|
|
case ID::Content_Note_CurrentNotebook:
|
|
return tr("Search the content of notes in current notebook");
|
|
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
return tr("Search the tags of notes in current notebook");
|
|
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
return tr("Search the name of folders/notes in current folder");
|
|
|
|
case ID::Content_Note_CurrentFolder:
|
|
return tr("Search the content of notes in current folder");
|
|
|
|
case ID::Tag_Note_CurrentFolder:
|
|
return tr("Search the tags of notes in current folder");
|
|
|
|
case ID::Name_Note_Buffer:
|
|
return tr("List and search the name of opened notes in buffer");
|
|
|
|
case ID::Content_Note_Buffer:
|
|
return tr("Search the content of opened notes in buffer");
|
|
|
|
case ID::Outline_Note_Buffer:
|
|
return tr("Search the outline of opened notes in buffer");
|
|
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
return tr("Search the path of folders/notes in all the notebooks");
|
|
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
return tr("Search the path of folders/notes in current notebook");
|
|
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
return tr("Search the content of notes in Explorer root directory");
|
|
|
|
default:
|
|
Q_ASSERT(false);
|
|
return tr("Invalid ID %1").arg(p_id);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::init()
|
|
{
|
|
if (m_initialized) {
|
|
return;
|
|
}
|
|
|
|
Q_ASSERT(m_widgetParent);
|
|
|
|
m_initialized = true;
|
|
|
|
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);
|
|
|
|
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");
|
|
|
|
m_listWidget = new VListWidgetDoubleRows(m_widgetParent);
|
|
m_listWidget->setFitContent(true);
|
|
m_listWidget->hide();
|
|
connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)),
|
|
this, SLOT(activateItem(QListWidgetItem *)));
|
|
|
|
m_treeWidget = new VTreeWidget(m_widgetParent);
|
|
m_treeWidget->setColumnCount(1);
|
|
m_treeWidget->setHeaderHidden(true);
|
|
m_treeWidget->setExpandsOnDoubleClick(false);
|
|
m_treeWidget->setFitContent(true);
|
|
m_treeWidget->hide();
|
|
connect(m_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
|
|
this, SLOT(activateItem(QTreeWidgetItem *, int)));
|
|
connect(m_treeWidget, &VTreeWidget::itemExpandedOrCollapsed,
|
|
this, &VSearchUE::widgetUpdated);
|
|
}
|
|
|
|
QWidget *VSearchUE::widget(int p_id)
|
|
{
|
|
init();
|
|
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
return m_listWidget;
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
return m_treeWidget;
|
|
|
|
default:
|
|
Q_ASSERT(false);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
void VSearchUE::processCommand(int p_id, const QString &p_cmd)
|
|
{
|
|
qDebug() << "processCommand" << p_id << p_cmd;
|
|
|
|
init();
|
|
|
|
clear(-1);
|
|
|
|
m_inSearch = true;
|
|
m_id = p_id;
|
|
emit stateUpdated(State::Busy);
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
searchNameOfAllNotebooks(p_cmd);
|
|
break;
|
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
searchNameOfFolderNoteInAllNotebooks(p_cmd);
|
|
break;
|
|
|
|
case ID::Tag_Note_AllNotebook:
|
|
searchTagOfNoteInAllNotebooks(p_cmd);
|
|
break;
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
searchContentOfNoteInAllNotebooks(p_cmd);
|
|
break;
|
|
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
searchNameOfFolderNoteInCurrentNotebook(p_cmd);
|
|
break;
|
|
|
|
case ID::Content_Note_CurrentNotebook:
|
|
searchContentOfNoteInCurrentNotebook(p_cmd);
|
|
break;
|
|
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
searchTagOfNoteInCurrentNotebook(p_cmd);
|
|
break;
|
|
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
searchNameOfFolderNoteInCurrentFolder(p_cmd);
|
|
break;
|
|
|
|
case ID::Content_Note_CurrentFolder:
|
|
searchContentOfNoteInCurrentFolder(p_cmd);
|
|
break;
|
|
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
searchContentOfNoteInExplorerDirectory(p_cmd);
|
|
break;
|
|
|
|
case ID::Tag_Note_CurrentFolder:
|
|
searchTagOfNoteInCurrentFolder(p_cmd);
|
|
break;
|
|
|
|
case ID::Name_Note_Buffer:
|
|
searchNameOfBuffer(p_cmd);
|
|
break;
|
|
|
|
case ID::Content_Note_Buffer:
|
|
searchContentOfBuffer(p_cmd);
|
|
break;
|
|
|
|
case ID::Outline_Note_Buffer:
|
|
searchOutlineOfBuffer(p_cmd);
|
|
break;
|
|
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
searchPathOfFolderNoteInAllNotebooks(p_cmd);
|
|
break;
|
|
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
searchPathOfFolderNoteInCurrentNotebook(p_cmd);
|
|
break;
|
|
|
|
default:
|
|
Q_ASSERT(false);
|
|
break;
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
void VSearchUE::searchNameOfAllNotebooks(const QString &p_cmd)
|
|
{
|
|
const QVector<VNotebook *> ¬ebooks = g_vnote->getNotebooks();
|
|
if (p_cmd.isEmpty()) {
|
|
// List all the notebooks.
|
|
for (auto const & nb : notebooks) {
|
|
QSharedPointer<VSearchResultItem> item(new VSearchResultItem(VSearchResultItem::Notebook,
|
|
VSearchResultItem::LineNumber,
|
|
nb->getName(),
|
|
nb->getPath()));
|
|
handleSearchItemAdded(item);
|
|
}
|
|
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
// Do a fuzzy search against the name of the notebooks.
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::AllNotebooks,
|
|
VSearchConfig::Name,
|
|
VSearchConfig::Notebook,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::Fuzzy,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
|
|
QSharedPointer<VSearchResult> result = m_search->search(notebooks);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::AllNotebooks,
|
|
VSearchConfig::Name,
|
|
VSearchConfig::Folder | VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(g_vnote->getNotebooks());
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchTagOfNoteInAllNotebooks(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::AllNotebooks,
|
|
VSearchConfig::Tag,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(g_vnote->getNotebooks());
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchTagOfNoteInCurrentNotebook(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
QVector<VNotebook *> notebooks;
|
|
notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook());
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentNotebook,
|
|
VSearchConfig::Tag,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(notebooks);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchTagOfNoteInCurrentFolder(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory();
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentFolder,
|
|
VSearchConfig::Tag,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(dir);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchContentOfNoteInAllNotebooks(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::AllNotebooks,
|
|
VSearchConfig::Content,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(g_vnote->getNotebooks());
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchNameOfFolderNoteInCurrentNotebook(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
QVector<VNotebook *> notebooks;
|
|
notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook());
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentNotebook,
|
|
VSearchConfig::Name,
|
|
VSearchConfig::Folder | VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(notebooks);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchContentOfNoteInCurrentNotebook(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
QVector<VNotebook *> notebooks;
|
|
notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook());
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentNotebook,
|
|
VSearchConfig::Content,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(notebooks);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchNameOfFolderNoteInCurrentFolder(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory();
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentFolder,
|
|
VSearchConfig::Name,
|
|
VSearchConfig::Folder | VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(dir);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchContentOfNoteInCurrentFolder(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
VDirectory *dir = g_mainWin->getDirectoryTree()->currentDirectory();
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentFolder,
|
|
VSearchConfig::Content,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(dir);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchContentOfNoteInExplorerDirectory(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
QString rootDirectory = g_mainWin->getExplorer()->getRootDirectory();
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::ExplorerDirectory,
|
|
VSearchConfig::Content,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(rootDirectory);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
QVector<VFile *> getFilesInBuffer()
|
|
{
|
|
QVector<VEditTabInfo> tabs = g_mainWin->getEditArea()->getAllTabsInfo();
|
|
QVector<VFile *> files;
|
|
files.reserve(tabs.size());
|
|
for (auto const & ta : tabs) {
|
|
files.append(ta.m_editTab->getFile());
|
|
}
|
|
|
|
return files;
|
|
}
|
|
|
|
void VSearchUE::searchNameOfBuffer(const QString &p_cmd)
|
|
{
|
|
QVector<VFile *> files = getFilesInBuffer();
|
|
if (p_cmd.isEmpty()) {
|
|
// List all the notes.
|
|
for (auto const & fi : files) {
|
|
QSharedPointer<VSearchResultItem> item(new VSearchResultItem(VSearchResultItem::Note,
|
|
VSearchResultItem::LineNumber,
|
|
fi->getName(),
|
|
fi->fetchPath()));
|
|
handleSearchItemAdded(item);
|
|
}
|
|
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::OpenedNotes,
|
|
VSearchConfig::Name,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(files);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchContentOfBuffer(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::OpenedNotes,
|
|
VSearchConfig::Content,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(getFilesInBuffer());
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchOutlineOfBuffer(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::OpenedNotes,
|
|
VSearchConfig::Outline,
|
|
VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(getFilesInBuffer());
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchPathOfFolderNoteInAllNotebooks(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::AllNotebooks,
|
|
VSearchConfig::Path,
|
|
VSearchConfig::Folder | VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(g_vnote->getNotebooks());
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::searchPathOfFolderNoteInCurrentNotebook(const QString &p_cmd)
|
|
{
|
|
if (p_cmd.isEmpty()) {
|
|
m_inSearch = false;
|
|
emit stateUpdated(State::Success);
|
|
} else {
|
|
QVector<VNotebook *> notebooks;
|
|
notebooks.append(g_mainWin->getNotebookSelector()->currentNotebook());
|
|
m_search->clear();
|
|
QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::CurrentNotebook,
|
|
VSearchConfig::Path,
|
|
VSearchConfig::Folder | VSearchConfig::Note,
|
|
VSearchConfig::Internal,
|
|
VSearchConfig::NoneOption,
|
|
p_cmd,
|
|
QString()));
|
|
m_search->setConfig(config);
|
|
QSharedPointer<VSearchResult> result = m_search->search(notebooks);
|
|
handleSearchFinished(result);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::clear(int p_id)
|
|
{
|
|
Q_UNUSED(p_id);
|
|
stopSearch();
|
|
|
|
m_data.clear();
|
|
m_listWidget->clearAll();
|
|
m_treeWidget->clearAll();
|
|
}
|
|
|
|
void VSearchUE::handleSearchItemAdded(const QSharedPointer<VSearchResultItem> &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:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
appendItemToList(p_item);
|
|
if (itemAdded > 50) {
|
|
itemAdded = 0;
|
|
m_listWidget->updateGeometry();
|
|
emit widgetUpdated();
|
|
}
|
|
|
|
break;
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
appendItemToTree(p_item);
|
|
if (itemAdded > 50) {
|
|
itemAdded = 0;
|
|
m_treeWidget->resizeColumnToContents(0);
|
|
m_treeWidget->updateGeometry();
|
|
emit widgetUpdated();
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void VSearchUE::handleSearchItemsAdded(const QList<QSharedPointer<VSearchResultItem> > &p_items)
|
|
{
|
|
QCoreApplication::sendPostedEvents(NULL, QEvent::KeyPress);
|
|
|
|
switch (m_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
{
|
|
for (auto const & it : p_items) {
|
|
appendItemToList(it);
|
|
}
|
|
|
|
m_listWidget->updateGeometry();
|
|
emit widgetUpdated();
|
|
break;
|
|
}
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
{
|
|
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<VSearchResultItem> &p_item)
|
|
{
|
|
m_data.append(p_item);
|
|
|
|
QString first, second;
|
|
if (p_item->m_text.isEmpty()) {
|
|
first = p_item->m_path;
|
|
} else {
|
|
if (p_item->m_type != VSearchResultItem::Notebook) {
|
|
first = VUniversalEntry::fileNameWithDir(p_item->m_text, p_item->m_path);
|
|
} else {
|
|
first = p_item->m_text;
|
|
}
|
|
second = p_item->m_path;
|
|
}
|
|
|
|
QIcon *icon = NULL;
|
|
// We put notebook and folder before note.
|
|
int row = 0;
|
|
switch (p_item->m_type) {
|
|
case VSearchResultItem::Note:
|
|
row = m_listWidget->count();
|
|
icon = &m_noteIcon;
|
|
break;
|
|
|
|
case VSearchResultItem::Folder:
|
|
icon = &m_folderIcon;
|
|
break;
|
|
|
|
case VSearchResultItem::Notebook:
|
|
icon = &m_notebookIcon;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
QListWidgetItem *item = m_listWidget->insertDoubleRowsItem(row, *icon, first, second);
|
|
item->setData(Qt::UserRole, m_data.size() - 1);
|
|
item->setToolTip(p_item->m_path);
|
|
|
|
if (row == 0) {
|
|
m_listWidget->setCurrentRow(0);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::appendItemToTree(const QSharedPointer<VSearchResultItem> &p_item)
|
|
{
|
|
m_data.append(p_item);
|
|
|
|
QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget);
|
|
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);
|
|
}
|
|
|
|
if (!m_treeWidget->currentItem()) {
|
|
m_treeWidget->setCurrentItem(item);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::handleSearchFinished(const QSharedPointer<VSearchResult> &p_result)
|
|
{
|
|
Q_ASSERT(m_inSearch);
|
|
Q_ASSERT(p_result->m_state != VSearchState::Idle);
|
|
|
|
qDebug() << "handleSearchFinished" << (int)p_result->m_state;
|
|
|
|
IUniversalEntry::State state = State::Idle;
|
|
|
|
bool finished = true;
|
|
switch (p_result->m_state) {
|
|
case VSearchState::Busy:
|
|
qDebug() << "search is ongoing";
|
|
state = State::Busy;
|
|
finished = false;
|
|
break;
|
|
|
|
case VSearchState::Success:
|
|
qDebug() << "search succeeded";
|
|
state = State::Success;
|
|
break;
|
|
|
|
case VSearchState::Fail:
|
|
qDebug() << "search failed";
|
|
state = State::Fail;
|
|
break;
|
|
|
|
case VSearchState::Cancelled:
|
|
qDebug() << "search cancelled";
|
|
state = State::Cancelled;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (finished) {
|
|
m_search->clear();
|
|
m_inSearch = false;
|
|
}
|
|
|
|
updateWidget();
|
|
|
|
emit stateUpdated(state);
|
|
}
|
|
|
|
void VSearchUE::stopSearch()
|
|
{
|
|
if (m_inSearch) {
|
|
m_search->stop();
|
|
|
|
while (m_inSearch) {
|
|
VUtils::sleepWait(100);
|
|
qDebug() << "sleep wait for search to stop";
|
|
}
|
|
}
|
|
}
|
|
|
|
const QSharedPointer<VSearchResultItem> &VSearchUE::itemResultData(const QListWidgetItem *p_item) const
|
|
{
|
|
Q_ASSERT(p_item);
|
|
int idx = p_item->data(Qt::UserRole).toInt();
|
|
Q_ASSERT(idx >= 0 && idx < m_data.size());
|
|
return m_data[idx];
|
|
}
|
|
|
|
const QSharedPointer<VSearchResultItem> &VSearchUE::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 VSearchUE::activateItem(const QSharedPointer<VSearchResultItem> &p_item, int p_matchIndex)
|
|
{
|
|
switch (p_item->m_type) {
|
|
case VSearchResultItem::Note:
|
|
{
|
|
bool highlightPage = false;
|
|
bool jumpTitle = false;
|
|
if (!p_item->m_matches.isEmpty() && p_item->m_config) {
|
|
if (p_item->m_config->m_object == VSearchConfig::Content) {
|
|
highlightPage = g_config->getHighlightMatchesInPage();
|
|
} else if (p_item->m_config->m_object == VSearchConfig::Outline) {
|
|
jumpTitle = true;
|
|
}
|
|
}
|
|
|
|
QStringList files(p_item->m_path);
|
|
OpenFileMode mode = highlightPage ? OpenFileMode::Edit : OpenFileMode::Read;
|
|
bool forceMode = highlightPage;
|
|
QVector<VFile *> openedFiles = g_mainWin->openFiles(files,
|
|
false,
|
|
mode,
|
|
forceMode);
|
|
if (openedFiles.size() == 1) {
|
|
VEditTab *tab = g_mainWin->getCurrentTab();
|
|
if (tab->getFile() != openedFiles.first()) {
|
|
break;
|
|
}
|
|
|
|
if (highlightPage) {
|
|
tab->findText(p_item->m_config->m_contentToken, true, true);
|
|
} else if (jumpTitle) {
|
|
if (p_matchIndex >= p_item->m_matches.size()) {
|
|
p_matchIndex = p_item->m_matches.size() - 1;
|
|
}
|
|
|
|
VHeaderPointer header(tab->getFile(),
|
|
p_item->m_matches[p_matchIndex].m_lineNumber);
|
|
tab->scrollToHeader(header);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case VSearchResultItem::Folder:
|
|
{
|
|
VDirectory *dir = g_vnote->getInternalDirectory(p_item->m_path);
|
|
if (dir) {
|
|
g_mainWin->locateDirectory(dir);
|
|
} else {
|
|
// External directory.
|
|
g_mainWin->showExplorerPanel(true);
|
|
g_mainWin->getExplorer()->setRootDirectory(p_item->m_path);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case VSearchResultItem::Notebook:
|
|
{
|
|
VNotebook *nb = g_vnote->getNotebook(p_item->m_path);
|
|
if (nb) {
|
|
g_mainWin->locateNotebook(nb);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void VSearchUE::activateItem(QListWidgetItem *p_item)
|
|
{
|
|
if (!p_item) {
|
|
return;
|
|
}
|
|
|
|
emit requestHideUniversalEntry();
|
|
activateItem(itemResultData(p_item));
|
|
}
|
|
|
|
void VSearchUE::activateItem(QTreeWidgetItem *p_item, int p_col)
|
|
{
|
|
Q_UNUSED(p_col);
|
|
if (!p_item) {
|
|
return;
|
|
}
|
|
|
|
emit requestHideUniversalEntry();
|
|
activateItem(itemResultData(p_item), VTreeWidget::childIndexOfTreeItem(p_item));
|
|
}
|
|
|
|
void VSearchUE::selectNextItem(int p_id, bool p_forward)
|
|
{
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
{
|
|
// Could not use postEvent method here which will induce infinite recursion.
|
|
m_listWidget->selectNextItem(p_forward);
|
|
break;
|
|
}
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
{
|
|
m_treeWidget->selectNextItem(p_forward);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
Q_ASSERT(false);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::activate(int p_id)
|
|
{
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
{
|
|
activateItem(m_listWidget->currentItem());
|
|
break;
|
|
}
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
{
|
|
activateItem(m_treeWidget->currentItem(), 0);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
Q_ASSERT(false);
|
|
}
|
|
}
|
|
|
|
void VSearchUE::askToStop(int p_id)
|
|
{
|
|
Q_UNUSED(p_id);
|
|
if (m_inSearch) {
|
|
m_search->stop();
|
|
}
|
|
}
|
|
|
|
void VSearchUE::selectParentItem(int p_id)
|
|
{
|
|
switch (p_id) {
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
m_treeWidget->selectParentItem();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void VSearchUE::toggleItemExpanded(int p_id)
|
|
{
|
|
switch (p_id) {
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
{
|
|
QTreeWidgetItem *item = m_treeWidget->currentItem();
|
|
if (item) {
|
|
item->setExpanded(!item->isExpanded());
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void VSearchUE::expandCollapseAll(int p_id)
|
|
{
|
|
switch (p_id) {
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
{
|
|
VTreeWidget::expandCollapseAll(m_treeWidget);
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void VSearchUE::sort(int p_id)
|
|
{
|
|
static bool noteFirst = false;
|
|
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
{
|
|
int cnt = m_listWidget->count();
|
|
if (noteFirst) {
|
|
int idx = cnt - 1;
|
|
while (true) {
|
|
if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) {
|
|
// Move it to the first row.
|
|
m_listWidget->moveItem(idx, 0);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
int idx = 0;
|
|
while (true) {
|
|
if (itemResultData(m_listWidget->item(idx))->m_type != VSearchResultItem::Note) {
|
|
// Move it to the last row.
|
|
m_listWidget->moveItem(idx, cnt - 1);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cnt) {
|
|
m_listWidget->setCurrentRow(0);
|
|
}
|
|
|
|
noteFirst = !noteFirst;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
QString VSearchUE::currentItemFolder(int p_id)
|
|
{
|
|
QString folder;
|
|
QSharedPointer<VSearchResultItem> resItem;
|
|
|
|
switch (p_id) {
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Tag_Note_AllNotebook:
|
|
case ID::Name_FolderNote_CurrentNotebook:
|
|
case ID::Tag_Note_CurrentNotebook:
|
|
case ID::Name_FolderNote_CurrentFolder:
|
|
case ID::Tag_Note_CurrentFolder:
|
|
case ID::Name_Note_Buffer:
|
|
case ID::Path_FolderNote_AllNotebook:
|
|
case ID::Path_FolderNote_CurrentNotebook:
|
|
{
|
|
QListWidgetItem *item = m_listWidget->currentItem();
|
|
if (item) {
|
|
resItem = itemResultData(item);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case ID::Content_Note_AllNotebook:
|
|
case ID::Content_Note_CurrentNotebook:
|
|
case ID::Content_Note_CurrentFolder:
|
|
case ID::Content_Note_ExplorerDirectory:
|
|
case ID::Content_Note_Buffer:
|
|
case ID::Outline_Note_Buffer:
|
|
{
|
|
QTreeWidgetItem *item = m_treeWidget->currentItem();
|
|
if (item) {
|
|
resItem = itemResultData(item);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
Q_ASSERT(false);
|
|
}
|
|
|
|
if (!resItem.isNull()) {
|
|
switch (resItem->m_type) {
|
|
case VSearchResultItem::Note:
|
|
folder = VUtils::basePathFromPath(resItem->m_path);
|
|
break;
|
|
|
|
case VSearchResultItem::Folder:
|
|
case VSearchResultItem::Notebook:
|
|
folder = resItem->m_path;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return folder;
|
|
}
|