|
@@ -4,10 +4,12 @@
|
|
|
#include <QVector>
|
|
#include <QVector>
|
|
|
|
|
|
|
|
#include "vlistwidgetdoublerows.h"
|
|
#include "vlistwidgetdoublerows.h"
|
|
|
|
|
+#include "vtreewidget.h"
|
|
|
#include "vnotebook.h"
|
|
#include "vnotebook.h"
|
|
|
#include "vnote.h"
|
|
#include "vnote.h"
|
|
|
#include "vsearch.h"
|
|
#include "vsearch.h"
|
|
|
#include "utils/viconutils.h"
|
|
#include "utils/viconutils.h"
|
|
|
|
|
+#include "utils/vutils.h"
|
|
|
#include "vmainwindow.h"
|
|
#include "vmainwindow.h"
|
|
|
#include "vnotebookselector.h"
|
|
#include "vnotebookselector.h"
|
|
|
#include "vnotefile.h"
|
|
#include "vnotefile.h"
|
|
@@ -20,8 +22,9 @@ VSearchUE::VSearchUE(QObject *p_parent)
|
|
|
: IUniversalEntry(p_parent),
|
|
: IUniversalEntry(p_parent),
|
|
|
m_search(NULL),
|
|
m_search(NULL),
|
|
|
m_inSearch(false),
|
|
m_inSearch(false),
|
|
|
|
|
+ m_id(ID::Name_Notebook_AllNotebook),
|
|
|
m_listWidget(NULL),
|
|
m_listWidget(NULL),
|
|
|
- m_id(ID::Name_Notebook_AllNotebook)
|
|
|
|
|
|
|
+ m_treeWidget(NULL)
|
|
|
{
|
|
{
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -34,6 +37,9 @@ QString VSearchUE::description(int p_id) const
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
|
return tr("Search the name of folders/notes in all notebooks");
|
|
return tr("Search the name of folders/notes in all notebooks");
|
|
|
|
|
|
|
|
|
|
+ case ID::Content_Note_AllNotebook:
|
|
|
|
|
+ return tr("Search the content of notes in all notebooks");
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
Q_ASSERT(false);
|
|
Q_ASSERT(false);
|
|
|
return tr("Invalid ID %1").arg(p_id);
|
|
return tr("Invalid ID %1").arg(p_id);
|
|
@@ -63,8 +69,20 @@ void VSearchUE::init()
|
|
|
m_listWidget = new VListWidgetDoubleRows(m_widgetParent);
|
|
m_listWidget = new VListWidgetDoubleRows(m_widgetParent);
|
|
|
m_listWidget->setFitContent(true);
|
|
m_listWidget->setFitContent(true);
|
|
|
m_listWidget->hide();
|
|
m_listWidget->hide();
|
|
|
- connect(m_listWidget, &VListWidgetDoubleRows::itemActivated,
|
|
|
|
|
- this, &VSearchUE::activateItem);
|
|
|
|
|
|
|
+ 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->setSimpleSearchMatchFlags(m_treeWidget->getSimpleSearchMatchFlags() & ~Qt::MatchRecursive);
|
|
|
|
|
+ m_treeWidget->setFitContent(true);
|
|
|
|
|
+ m_treeWidget->hide();
|
|
|
|
|
+ connect(m_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
|
|
|
|
|
+ this, SLOT(activateItem(QTreeWidgetItem *, int)));
|
|
|
|
|
+ connect(m_treeWidget, &VTreeWidget::itemExpanded,
|
|
|
|
|
+ this, &VSearchUE::widgetUpdated);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
QWidget *VSearchUE::widget(int p_id)
|
|
QWidget *VSearchUE::widget(int p_id)
|
|
@@ -73,10 +91,12 @@ QWidget *VSearchUE::widget(int p_id)
|
|
|
|
|
|
|
|
switch (p_id) {
|
|
switch (p_id) {
|
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_Notebook_AllNotebook:
|
|
|
- V_FALLTHROUGH;
|
|
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
|
return m_listWidget;
|
|
return m_listWidget;
|
|
|
|
|
|
|
|
|
|
+ case ID::Content_Note_AllNotebook:
|
|
|
|
|
+ return m_treeWidget;
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
Q_ASSERT(false);
|
|
Q_ASSERT(false);
|
|
|
return NULL;
|
|
return NULL;
|
|
@@ -103,6 +123,10 @@ void VSearchUE::processCommand(int p_id, const QString &p_cmd)
|
|
|
searchNameOfFolderNoteInAllNotebooks(p_cmd);
|
|
searchNameOfFolderNoteInAllNotebooks(p_cmd);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ case ID::Content_Note_AllNotebook:
|
|
|
|
|
+ searchContentOfNoteInAllNotebooks(p_cmd);
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
Q_ASSERT(false);
|
|
Q_ASSERT(false);
|
|
|
break;
|
|
break;
|
|
@@ -165,6 +189,27 @@ void VSearchUE::searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void VSearchUE::searchContentOfNoteInAllNotebooks(const QString &p_cmd)
|
|
|
|
|
+{
|
|
|
|
|
+ const QVector<VNotebook *> ¬ebooks = g_vnote->getNotebooks();
|
|
|
|
|
+ if (p_cmd.isEmpty()) {
|
|
|
|
|
+ m_inSearch = false;
|
|
|
|
|
+ emit stateUpdated(State::Success);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ VSearchConfig::Option opt = VSearchConfig::NoneOption;
|
|
|
|
|
+ QSharedPointer<VSearchConfig> config(new VSearchConfig(VSearchConfig::AllNotebooks,
|
|
|
|
|
+ VSearchConfig::Content,
|
|
|
|
|
+ VSearchConfig::Note,
|
|
|
|
|
+ VSearchConfig::Internal,
|
|
|
|
|
+ opt,
|
|
|
|
|
+ p_cmd,
|
|
|
|
|
+ QString()));
|
|
|
|
|
+ m_search->setConfig(config);
|
|
|
|
|
+ QSharedPointer<VSearchResult> result = m_search->search(notebooks);
|
|
|
|
|
+ handleSearchFinished(result);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void VSearchUE::clear(int p_id)
|
|
void VSearchUE::clear(int p_id)
|
|
|
{
|
|
{
|
|
|
Q_UNUSED(p_id);
|
|
Q_UNUSED(p_id);
|
|
@@ -172,6 +217,7 @@ void VSearchUE::clear(int p_id)
|
|
|
|
|
|
|
|
m_data.clear();
|
|
m_data.clear();
|
|
|
m_listWidget->clearAll();
|
|
m_listWidget->clearAll();
|
|
|
|
|
+ m_treeWidget->clearAll();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void VSearchUE::entryHidden(int p_id)
|
|
void VSearchUE::entryHidden(int p_id)
|
|
@@ -183,11 +229,14 @@ void VSearchUE::handleSearchItemAdded(const QSharedPointer<VSearchResultItem> &p
|
|
|
{
|
|
{
|
|
|
switch (m_id) {
|
|
switch (m_id) {
|
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_Notebook_AllNotebook:
|
|
|
- V_FALLTHROUGH;
|
|
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
|
appendItemToList(p_item);
|
|
appendItemToList(p_item);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
|
|
+ case ID::Content_Note_AllNotebook:
|
|
|
|
|
+ appendItemToTree(p_item);
|
|
|
|
|
+ break;
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -228,13 +277,67 @@ void VSearchUE::appendItemToList(const QSharedPointer<VSearchResultItem> &p_item
|
|
|
item->setData(Qt::UserRole, m_data.size() - 1);
|
|
item->setData(Qt::UserRole, m_data.size() - 1);
|
|
|
item->setToolTip(p_item->m_path);
|
|
item->setToolTip(p_item->m_path);
|
|
|
|
|
|
|
|
|
|
+ ++itemAdded;
|
|
|
if (m_listWidget->currentRow() == -1) {
|
|
if (m_listWidget->currentRow() == -1) {
|
|
|
m_listWidget->setCurrentRow(0);
|
|
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<VSearchResultItem> &p_item)
|
|
|
|
|
+{
|
|
|
|
|
+ static int itemAdded = 0;
|
|
|
|
|
+ m_data.append(p_item);
|
|
|
|
|
+
|
|
|
|
|
+ QTreeWidgetItem *item = new QTreeWidgetItem(m_treeWidget);
|
|
|
|
|
+ item->setData(0, Qt::UserRole, m_data.size() - 1);
|
|
|
|
|
+ item->setText(0, p_item->m_text.isEmpty() ? p_item->m_path : p_item->m_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 (++itemAdded >= 10) {
|
|
|
|
|
|
|
+ ++itemAdded;
|
|
|
|
|
+ if (!m_treeWidget->currentItem()) {
|
|
|
|
|
+ m_treeWidget->setCurrentItem(item);
|
|
|
|
|
+ m_treeWidget->resizeColumnToContents(0);
|
|
|
|
|
+ m_treeWidget->updateGeometry();
|
|
|
|
|
+ emit widgetUpdated();
|
|
|
|
|
+ } else if (itemAdded >= 20) {
|
|
|
itemAdded = 0;
|
|
itemAdded = 0;
|
|
|
- m_listWidget->updateGeometry();
|
|
|
|
|
|
|
+ m_treeWidget->updateGeometry();
|
|
|
emit widgetUpdated();
|
|
emit widgetUpdated();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -248,11 +351,13 @@ void VSearchUE::handleSearchFinished(const QSharedPointer<VSearchResult> &p_resu
|
|
|
|
|
|
|
|
IUniversalEntry::State state = State::Idle;
|
|
IUniversalEntry::State state = State::Idle;
|
|
|
|
|
|
|
|
|
|
+ bool finished = true;
|
|
|
switch (p_result->m_state) {
|
|
switch (p_result->m_state) {
|
|
|
case VSearchState::Busy:
|
|
case VSearchState::Busy:
|
|
|
qDebug() << "search is ongoing";
|
|
qDebug() << "search is ongoing";
|
|
|
state = State::Busy;
|
|
state = State::Busy;
|
|
|
- return;
|
|
|
|
|
|
|
+ finished = false;
|
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
case VSearchState::Success:
|
|
case VSearchState::Success:
|
|
|
qDebug() << "search succeeded";
|
|
qDebug() << "search succeeded";
|
|
@@ -273,10 +378,17 @@ void VSearchUE::handleSearchFinished(const QSharedPointer<VSearchResult> &p_resu
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- m_search->clear();
|
|
|
|
|
- m_inSearch = false;
|
|
|
|
|
|
|
+ if (finished) {
|
|
|
|
|
+ m_search->clear();
|
|
|
|
|
+ m_inSearch = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ QWidget *wid = widget(m_id);
|
|
|
|
|
+ if (wid == m_treeWidget) {
|
|
|
|
|
+ m_treeWidget->resizeColumnToContents(0);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- widget(m_id)->updateGeometry();
|
|
|
|
|
|
|
+ wid->updateGeometry();
|
|
|
emit widgetUpdated();
|
|
emit widgetUpdated();
|
|
|
|
|
|
|
|
emit stateUpdated(state);
|
|
emit stateUpdated(state);
|
|
@@ -302,26 +414,28 @@ const QSharedPointer<VSearchResultItem> &VSearchUE::itemResultData(const QListWi
|
|
|
return m_data[idx];
|
|
return m_data[idx];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-void VSearchUE::activateItem(const QListWidgetItem *p_item)
|
|
|
|
|
|
|
+const QSharedPointer<VSearchResultItem> &VSearchUE::itemResultData(const QTreeWidgetItem *p_item) const
|
|
|
{
|
|
{
|
|
|
- if (!p_item) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- emit requestHideUniversalEntry();
|
|
|
|
|
|
|
+ Q_ASSERT(p_item);
|
|
|
|
|
+ const QTreeWidgetItem *topItem = VUtils::topLevelTreeItem(p_item);
|
|
|
|
|
+ int idx = topItem->data(0, Qt::UserRole).toInt();
|
|
|
|
|
+ Q_ASSERT(idx >= 0 && idx < m_data.size());
|
|
|
|
|
+ return m_data[idx];
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
- const QSharedPointer<VSearchResultItem> &resItem = itemResultData(p_item);
|
|
|
|
|
- switch (resItem->m_type) {
|
|
|
|
|
|
|
+void VSearchUE::activateItem(const QSharedPointer<VSearchResultItem> &p_item)
|
|
|
|
|
+{
|
|
|
|
|
+ switch (p_item->m_type) {
|
|
|
case VSearchResultItem::Note:
|
|
case VSearchResultItem::Note:
|
|
|
{
|
|
{
|
|
|
- QStringList files(resItem->m_path);
|
|
|
|
|
|
|
+ QStringList files(p_item->m_path);
|
|
|
g_mainWin->openFiles(files);
|
|
g_mainWin->openFiles(files);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
case VSearchResultItem::Folder:
|
|
case VSearchResultItem::Folder:
|
|
|
{
|
|
{
|
|
|
- VDirectory *dir = g_vnote->getInternalDirectory(resItem->m_path);
|
|
|
|
|
|
|
+ VDirectory *dir = g_vnote->getInternalDirectory(p_item->m_path);
|
|
|
if (dir) {
|
|
if (dir) {
|
|
|
g_mainWin->locateDirectory(dir);
|
|
g_mainWin->locateDirectory(dir);
|
|
|
}
|
|
}
|
|
@@ -331,7 +445,7 @@ void VSearchUE::activateItem(const QListWidgetItem *p_item)
|
|
|
|
|
|
|
|
case VSearchResultItem::Notebook:
|
|
case VSearchResultItem::Notebook:
|
|
|
{
|
|
{
|
|
|
- VNotebook *nb = g_vnote->getNotebook(resItem->m_path);
|
|
|
|
|
|
|
+ VNotebook *nb = g_vnote->getNotebook(p_item->m_path);
|
|
|
if (nb) {
|
|
if (nb) {
|
|
|
g_mainWin->getNotebookSelector()->locateNotebook(nb);
|
|
g_mainWin->getNotebookSelector()->locateNotebook(nb);
|
|
|
}
|
|
}
|
|
@@ -344,11 +458,31 @@ void VSearchUE::activateItem(const QListWidgetItem *p_item)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+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));
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void VSearchUE::selectNextItem(int p_id, bool p_forward)
|
|
void VSearchUE::selectNextItem(int p_id, bool p_forward)
|
|
|
{
|
|
{
|
|
|
switch (p_id) {
|
|
switch (p_id) {
|
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_Notebook_AllNotebook:
|
|
|
- V_FALLTHROUGH;
|
|
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
|
{
|
|
{
|
|
|
// Could not use postEvent method here which will induce infinite recursion.
|
|
// Could not use postEvent method here which will induce infinite recursion.
|
|
@@ -356,6 +490,12 @@ void VSearchUE::selectNextItem(int p_id, bool p_forward)
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ case ID::Content_Note_AllNotebook:
|
|
|
|
|
+ {
|
|
|
|
|
+ m_treeWidget->selectNextItem(p_forward);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
Q_ASSERT(false);
|
|
Q_ASSERT(false);
|
|
|
}
|
|
}
|
|
@@ -365,13 +505,18 @@ void VSearchUE::activate(int p_id)
|
|
|
{
|
|
{
|
|
|
switch (p_id) {
|
|
switch (p_id) {
|
|
|
case ID::Name_Notebook_AllNotebook:
|
|
case ID::Name_Notebook_AllNotebook:
|
|
|
- V_FALLTHROUGH;
|
|
|
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
case ID::Name_FolderNote_AllNotebook:
|
|
|
{
|
|
{
|
|
|
activateItem(m_listWidget->currentItem());
|
|
activateItem(m_listWidget->currentItem());
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ case ID::Content_Note_AllNotebook:
|
|
|
|
|
+ {
|
|
|
|
|
+ activateItem(m_treeWidget->currentItem(), 0);
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
default:
|
|
default:
|
|
|
Q_ASSERT(false);
|
|
Q_ASSERT(false);
|
|
|
}
|
|
}
|