VSearch: support searching Explorer directory

This commit is contained in:
Le Tan 2018-07-18 20:04:57 +08:00
parent 98f2238dd1
commit 5f65dc95c5
7 changed files with 213 additions and 15 deletions

View File

@ -783,3 +783,14 @@ void VExplorer::keyPressEvent(QKeyEvent *p_event)
QWidget::keyPressEvent(p_event); QWidget::keyPressEvent(p_event);
} }
QString VExplorer::getRootDirectory() const
{
const_cast<VExplorer *>(this)->init();
if (checkIndex()) {
return m_entries[m_index].m_directory;
}
return QString();
}

View File

@ -23,6 +23,8 @@ public:
void setRootDirectory(const QString &p_path); void setRootDirectory(const QString &p_path);
QString getRootDirectory() const;
protected: protected:
void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE; void showEvent(QShowEvent *p_event) Q_DECL_OVERRIDE;

View File

@ -133,6 +133,39 @@ QSharedPointer<VSearchResult> VSearch::search(const QVector<VNotebook *> &p_note
return result; return result;
} }
QSharedPointer<VSearchResult> VSearch::search(const QString &p_directoryPath)
{
Q_ASSERT(!askedToStop());
QSharedPointer<VSearchResult> result(new VSearchResult(this));
if (p_directoryPath.isEmpty() || m_config->isEmpty()) {
result->m_state = VSearchState::Success;
return result;
}
if ((!testTarget(VSearchConfig::Note)
&& !testTarget(VSearchConfig::Folder))
|| testObject(VSearchConfig::Outline)
|| testObject(VSearchConfig::Tag)) {
qDebug() << "search is not applicable for directory";
result->m_state = VSearchState::Success;
return result;
}
result->m_state = VSearchState::Busy;
searchFirstPhase(p_directoryPath, p_directoryPath, result);
if (result->hasSecondPhaseItems()) {
searchSecondPhase(result);
} else if (result->m_state == VSearchState::Busy) {
result->m_state = VSearchState::Success;
}
return result;
}
void VSearch::searchFirstPhase(VFile *p_file, void VSearch::searchFirstPhase(VFile *p_file,
const QSharedPointer<VSearchResult> &p_result, const QSharedPointer<VSearchResult> &p_result,
bool p_searchContent) bool p_searchContent)
@ -209,10 +242,7 @@ void VSearch::searchFirstPhase(VFile *p_file,
void VSearch::searchFirstPhase(VDirectory *p_directory, void VSearch::searchFirstPhase(VDirectory *p_directory,
const QSharedPointer<VSearchResult> &p_result) const QSharedPointer<VSearchResult> &p_result)
{ {
if (!testTarget(VSearchConfig::Note) Q_ASSERT(testTarget(VSearchConfig::Note) || testTarget(VSearchConfig::Folder));
&& !testTarget(VSearchConfig::Folder)) {
return;
}
bool opened = p_directory->isOpened(); bool opened = p_directory->isOpened();
if (!opened && !p_directory->open()) { if (!opened && !p_directory->open()) {
@ -324,6 +354,116 @@ exit:
} }
} }
void VSearch::searchFirstPhase(const QString &p_basePath,
const QString &p_directoryPath,
const QSharedPointer<VSearchResult> &p_result)
{
Q_ASSERT(testTarget(VSearchConfig::Note) || testTarget(VSearchConfig::Folder));
Q_ASSERT(!p_directoryPath.isEmpty());
QDir dir(p_directoryPath);
if (!dir.exists()) {
p_result->logError(QString("Directory %1 does not exist.").arg(p_directoryPath));
p_result->m_state = VSearchState::Fail;
return;
}
Q_ASSERT(dir.isAbsolute());
if (testTarget(VSearchConfig::Folder)) {
QString name = dir.dirName();
if (testObject(VSearchConfig::Name)) {
if (matchNonContent(name)) {
VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Folder,
VSearchResultItem::LineNumber,
name,
p_directoryPath);
QSharedPointer<VSearchResultItem> pitem(item);
emit resultItemAdded(pitem);
}
}
if (testObject(VSearchConfig::Path)) {
QString normPath(QDir(p_basePath).relativeFilePath(p_directoryPath));
removeSlashFromPath(normPath);
if (matchNonContent(normPath)) {
VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Folder,
VSearchResultItem::LineNumber,
name,
p_directoryPath);
QSharedPointer<VSearchResultItem> pitem(item);
emit resultItemAdded(pitem);
}
}
}
if (testTarget(VSearchConfig::Note)) {
QStringList files = dir.entryList(QDir::Files);
for (auto const & file : files) {
if (askedToStop()) {
qDebug() << "asked to cancel the search";
p_result->m_state = VSearchState::Cancelled;
return;
}
searchFirstPhaseFile(p_basePath, dir.absoluteFilePath(file), p_result);
}
}
// Search subfolders.
QStringList subdirs = dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
for (auto const & sub : subdirs) {
if (askedToStop()) {
qDebug() << "asked to cancel the search";
p_result->m_state = VSearchState::Cancelled;
return;
}
searchFirstPhase(p_basePath, dir.absoluteFilePath(sub), p_result);
}
}
void VSearch::searchFirstPhaseFile(const QString &p_basePath,
const QString &p_filePath,
const QSharedPointer<VSearchResult> &p_result)
{
Q_ASSERT(testTarget(VSearchConfig::Note));
QString name = VUtils::fileNameFromPath(p_filePath);
if (!matchPattern(name)) {
return;
}
if (testObject(VSearchConfig::Name)) {
if (matchNonContent(name)) {
VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Note,
VSearchResultItem::LineNumber,
name,
p_filePath);
QSharedPointer<VSearchResultItem> pitem(item);
emit resultItemAdded(pitem);
}
}
if (testObject(VSearchConfig::Path)) {
QString normFilePath(QDir(p_basePath).relativeFilePath(p_filePath));
removeSlashFromPath(normFilePath);
if (matchNonContent(normFilePath)) {
VSearchResultItem *item = new VSearchResultItem(VSearchResultItem::Note,
VSearchResultItem::LineNumber,
name,
p_filePath);
QSharedPointer<VSearchResultItem> pitem(item);
emit resultItemAdded(pitem);
}
}
if (testObject(VSearchConfig::Content)) {
// Add an item for second phase process.
p_result->addSecondPhaseItem(p_filePath);
}
}
VSearchResultItem *VSearch::searchForOutline(const VFile *p_file) const VSearchResultItem *VSearch::searchForOutline(const VFile *p_file) const
{ {
VEditTab *tab = g_mainWin->getEditArea()->getTab(p_file); VEditTab *tab = g_mainWin->getEditArea()->getTab(p_file);

View File

@ -32,6 +32,9 @@ public:
// Search folder for CurrentNotebook and AllNotebooks. // Search folder for CurrentNotebook and AllNotebooks.
QSharedPointer<VSearchResult> search(const QVector<VNotebook *> &p_notebooks); QSharedPointer<VSearchResult> search(const QVector<VNotebook *> &p_notebooks);
// Search directory path for ExplorerDirectory.
QSharedPointer<VSearchResult> search(const QString &p_directoryPath);
// Clear resources after a search completed. // Clear resources after a search completed.
void clear(); void clear();
@ -60,6 +63,14 @@ private:
void searchFirstPhase(VNotebook *p_notebook, void searchFirstPhase(VNotebook *p_notebook,
const QSharedPointer<VSearchResult> &p_result); const QSharedPointer<VSearchResult> &p_result);
void searchFirstPhase(const QString &p_basePath,
const QString &p_directoryPath,
const QSharedPointer<VSearchResult> &p_result);
void searchFirstPhaseFile(const QString &p_basePath,
const QString &p_filePath,
const QSharedPointer<VSearchResult> &p_result);
bool testTarget(VSearchConfig::Target p_target) const; bool testTarget(VSearchConfig::Target p_target) const;
bool testObject(VSearchConfig::Object p_object) const; bool testObject(VSearchConfig::Object p_object) const;

View File

@ -194,7 +194,8 @@ struct VSearchConfig
OpenedNotes, OpenedNotes,
CurrentFolder, CurrentFolder,
CurrentNotebook, CurrentNotebook,
AllNotebooks AllNotebooks,
ExplorerDirectory
}; };
enum Object enum Object

View File

@ -16,6 +16,7 @@
#include "vnotebook.h" #include "vnotebook.h"
#include "vnote.h" #include "vnote.h"
#include "vconfigmanager.h" #include "vconfigmanager.h"
#include "vexplorer.h"
extern VMainWindow *g_mainWin; extern VMainWindow *g_mainWin;
@ -243,12 +244,14 @@ void VSearcher::initUIFields()
m_searchScopeCB->addItem(tr("Current Folder"), VSearchConfig::CurrentFolder); m_searchScopeCB->addItem(tr("Current Folder"), VSearchConfig::CurrentFolder);
m_searchScopeCB->addItem(tr("Current Notebook"), VSearchConfig::CurrentNotebook); m_searchScopeCB->addItem(tr("Current Notebook"), VSearchConfig::CurrentNotebook);
m_searchScopeCB->addItem(tr("All Notebooks"), VSearchConfig::AllNotebooks); m_searchScopeCB->addItem(tr("All Notebooks"), VSearchConfig::AllNotebooks);
m_searchScopeCB->addItem(tr("Explorer Directory"), VSearchConfig::ExplorerDirectory);
m_searchScopeCB->setCurrentIndex(m_searchScopeCB->findData(config.m_scope)); m_searchScopeCB->setCurrentIndex(m_searchScopeCB->findData(config.m_scope));
// Object. // Object.
m_searchObjectCB->addItem(tr("Name"), VSearchConfig::Name); m_searchObjectCB->addItem(tr("Name"), VSearchConfig::Name);
m_searchObjectCB->addItem(tr("Content"), VSearchConfig::Content); m_searchObjectCB->addItem(tr("Content"), VSearchConfig::Content);
m_searchObjectCB->addItem(tr("Tag"), VSearchConfig::Tag); m_searchObjectCB->addItem(tr("Tag"), VSearchConfig::Tag);
m_searchObjectCB->addItem(tr("Path"), VSearchConfig::Path);
m_searchObjectCB->setCurrentIndex(m_searchObjectCB->findData(config.m_object)); m_searchObjectCB->setCurrentIndex(m_searchObjectCB->findData(config.m_object));
// Target. // Target.
@ -314,20 +317,32 @@ void VSearcher::handleInputChanged()
readyToSearch = !keyword.isEmpty(); readyToSearch = !keyword.isEmpty();
if (readyToSearch) { if (readyToSearch) {
// Other targets are only available for Name and Path.
int obj = m_searchObjectCB->currentData().toInt(); int obj = m_searchObjectCB->currentData().toInt();
if (obj != VSearchConfig::Name && obj != VSearchConfig::Path) {
int target = m_searchTargetCB->currentData().toInt(); int target = m_searchTargetCB->currentData().toInt();
if (!(target & VSearchConfig::Note)) { int scope = m_searchScopeCB->currentData().toInt();
// Other targets are only available for Name and Path.
if (!(obj & VSearchConfig::Name)
&& !(obj & VSearchConfig::Path)
&& !(target & VSearchConfig::Note)) {
readyToSearch = false; readyToSearch = false;
} }
if (readyToSearch
&& obj == VSearchConfig::Outline
&& scope != VSearchConfig::CurrentNotebook
&& scope != VSearchConfig::OpenedNotes) {
// Outline is available only for CurrentNote and OpenedNotes.
readyToSearch = false;
} }
if (readyToSearch && obj == VSearchConfig::Outline) { if (readyToSearch && scope == VSearchConfig::ExplorerDirectory) {
// Outline is available only for CurrentNote and OpenedNotes. if (!(obj & VSearchConfig::Name)
int scope = m_searchScopeCB->currentData().toInt(); && !(obj & VSearchConfig::Path)
if (scope != VSearchConfig::CurrentNote && !(obj & VSearchConfig::Content)) {
&& scope != VSearchConfig::OpenedNotes) { readyToSearch = false;
} else if (!(target & VSearchConfig::Note)
&& !(target & VSearchConfig::Folder)) {
readyToSearch = false; readyToSearch = false;
} }
} }
@ -429,6 +444,19 @@ void VSearcher::startSearch()
break; break;
} }
case VSearchConfig::ExplorerDirectory:
{
QString rootDirectory = g_mainWin->getExplorer()->getRootDirectory();
if (!rootDirectory.isEmpty()) {
QString msg(tr("Search Explorer directory %1.").arg(rootDirectory));
appendLogLine(msg);
showMessage(msg);
}
result = m_search.search(rootDirectory);
break;
}
default: default:
break; break;
} }

View File

@ -10,6 +10,7 @@
#include "vnotefile.h" #include "vnotefile.h"
#include "vcart.h" #include "vcart.h"
#include "vhistorylist.h" #include "vhistorylist.h"
#include "vexplorer.h"
extern VNote *g_vnote; extern VNote *g_vnote;
@ -272,6 +273,10 @@ void VSearchResultTree::activateItem(const QTreeWidgetItem *p_item) const
VDirectory *dir = g_vnote->getInternalDirectory(resItem->m_path); VDirectory *dir = g_vnote->getInternalDirectory(resItem->m_path);
if (dir) { if (dir) {
g_mainWin->locateDirectory(dir); g_mainWin->locateDirectory(dir);
} else {
// External directory.
g_mainWin->showExplorerPanel(true);
g_mainWin->getExplorer()->setRootDirectory(resItem->m_path);
} }
break; break;