mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
UniversalEntry: add z to search content of note in all notebooks
This commit is contained in:
parent
b46a8f4f39
commit
a2c2d57570
@ -25,6 +25,7 @@
|
|||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QWebEngineView>
|
#include <QWebEngineView>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
|
#include <QTreeWidgetItem>
|
||||||
|
|
||||||
#include "vorphanfile.h"
|
#include "vorphanfile.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
@ -1390,3 +1391,16 @@ QStringList VUtils::parseCombinedArgString(const QString &p_program)
|
|||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const QTreeWidgetItem *VUtils::topLevelTreeItem(const QTreeWidgetItem *p_item)
|
||||||
|
{
|
||||||
|
if (!p_item) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_item->parent()) {
|
||||||
|
return p_item->parent();
|
||||||
|
} else {
|
||||||
|
return p_item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@ class QWidget;
|
|||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QWebEngineView;
|
class QWebEngineView;
|
||||||
class QAction;
|
class QAction;
|
||||||
|
class QTreeWidgetItem;
|
||||||
|
|
||||||
#if !defined(V_ASSERT)
|
#if !defined(V_ASSERT)
|
||||||
#define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop())
|
#define V_ASSERT(cond) ((!(cond)) ? qt_assert(#cond, __FILE__, __LINE__) : qt_noop())
|
||||||
@ -314,6 +315,8 @@ public:
|
|||||||
// From QProcess code.
|
// From QProcess code.
|
||||||
static QStringList parseCombinedArgString(const QString &p_program);
|
static QStringList parseCombinedArgString(const QString &p_program);
|
||||||
|
|
||||||
|
static const QTreeWidgetItem *topLevelTreeItem(const QTreeWidgetItem *p_item);
|
||||||
|
|
||||||
// Regular expression for image link.
|
// Regular expression for image link.
|
||||||
// 
|
// 
|
||||||
// Captured texts (need to be trimmed):
|
// Captured texts (need to be trimmed):
|
||||||
|
@ -176,11 +176,11 @@ void VListWidget::sortListWidget(QListWidget *p_list, const QVector<int> &p_sort
|
|||||||
|
|
||||||
QSize VListWidget::sizeHint() const
|
QSize VListWidget::sizeHint() const
|
||||||
{
|
{
|
||||||
if (count() == 0 || !m_fitContent) {
|
int cnt = count();
|
||||||
|
if (cnt == 0 || !m_fitContent) {
|
||||||
return QListWidget::sizeHint();
|
return QListWidget::sizeHint();
|
||||||
} else {
|
} else {
|
||||||
// Adjust size to content.
|
// Adjust size to content.
|
||||||
int cnt = count();
|
|
||||||
int hei = 0;
|
int hei = 0;
|
||||||
int wid = sizeHintForColumn(0) + 10;
|
int wid = sizeHintForColumn(0) + 10;
|
||||||
for (int i = 0; i < cnt; ++i) {
|
for (int i = 0; i < cnt; ++i) {
|
||||||
|
@ -32,7 +32,7 @@ public:
|
|||||||
|
|
||||||
virtual void selectNextItem(bool p_forward) Q_DECL_OVERRIDE;
|
virtual void selectNextItem(bool p_forward) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
QSize sizeHint() const Q_DECL_OVERRIDE;
|
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
// Sort @p_list according to @p_sortedIdx.
|
// Sort @p_list according to @p_sortedIdx.
|
||||||
static void sortListWidget(QListWidget *p_list, const QVector<int> &p_sortedIdx);
|
static void sortListWidget(QListWidget *p_list, const QVector<int> &p_sortedIdx);
|
||||||
|
@ -3201,4 +3201,5 @@ void VMainWindow::initUniversalEntry()
|
|||||||
VSearchUE *searchUE = new VSearchUE(this);
|
VSearchUE *searchUE = new VSearchUE(this);
|
||||||
m_ue->registerEntry('q', searchUE, VSearchUE::Name_Notebook_AllNotebook);
|
m_ue->registerEntry('q', searchUE, VSearchUE::Name_Notebook_AllNotebook);
|
||||||
m_ue->registerEntry('a', searchUE, VSearchUE::Name_FolderNote_AllNotebook);
|
m_ue->registerEntry('a', searchUE, VSearchUE::Name_FolderNote_AllNotebook);
|
||||||
|
m_ue->registerEntry('z', searchUE, VSearchUE::Content_Note_AllNotebook);
|
||||||
}
|
}
|
||||||
|
@ -259,6 +259,16 @@ struct VSearchConfig
|
|||||||
compileToken(p_keyword);
|
compileToken(p_keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We support some magic switch in the keyword which will suppress the specified
|
||||||
|
// options:
|
||||||
|
// \c: Case insensitive;
|
||||||
|
// \C: Case sensitive;
|
||||||
|
// \r: Turn off regular expression;
|
||||||
|
// \R: Turn on regular expression;
|
||||||
|
// \f: Turn off fuzzy search;
|
||||||
|
// \F: Turn on fuzzy search (invalid when searching content);
|
||||||
|
// \w: Turn off whole word only;
|
||||||
|
// \W: Turn on whole word only;
|
||||||
void compileToken(const QString &p_keyword)
|
void compileToken(const QString &p_keyword)
|
||||||
{
|
{
|
||||||
m_token.clear();
|
m_token.clear();
|
||||||
@ -267,12 +277,48 @@ struct VSearchConfig
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// """ to input a ";
|
||||||
|
// && for AND, || for OR;
|
||||||
|
QStringList args = VUtils::parseCombinedArgString(p_keyword);
|
||||||
|
|
||||||
Qt::CaseSensitivity cs = m_option & VSearchConfig::CaseSensitive
|
Qt::CaseSensitivity cs = m_option & VSearchConfig::CaseSensitive
|
||||||
? Qt::CaseSensitive : Qt::CaseInsensitive;
|
? Qt::CaseSensitive : Qt::CaseInsensitive;
|
||||||
bool useReg = m_option & VSearchConfig::RegularExpression;
|
bool useReg = m_option & VSearchConfig::RegularExpression;
|
||||||
bool wwo = m_option & VSearchConfig::WholeWordOnly;
|
bool wwo = m_option & VSearchConfig::WholeWordOnly;
|
||||||
bool fuzzy = m_option & VSearchConfig::Fuzzy;
|
bool fuzzy = m_option & VSearchConfig::Fuzzy;
|
||||||
|
|
||||||
|
// Read magic switch from keyword.
|
||||||
|
for (int i = 0; i < args.size();) {
|
||||||
|
const QString &arg = args[i];
|
||||||
|
if (arg.size() != 2 || arg[0] != '\\') {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg == "\\c") {
|
||||||
|
cs = Qt::CaseInsensitive;
|
||||||
|
} else if (arg == "\\C") {
|
||||||
|
cs = Qt::CaseSensitive;
|
||||||
|
} else if (arg == "\\r") {
|
||||||
|
useReg = false;
|
||||||
|
} else if (arg == "\\R") {
|
||||||
|
useReg = true;
|
||||||
|
} else if (arg == "\\f") {
|
||||||
|
fuzzy = false;
|
||||||
|
} else if (arg == "\\F") {
|
||||||
|
fuzzy = true;
|
||||||
|
} else if (arg == "\\w") {
|
||||||
|
wwo = false;
|
||||||
|
} else if (arg == "\\W") {
|
||||||
|
wwo = true;
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.removeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
m_token.m_caseSensitivity = cs;
|
m_token.m_caseSensitivity = cs;
|
||||||
m_contentToken.m_caseSensitivity = cs;
|
m_contentToken.m_caseSensitivity = cs;
|
||||||
|
|
||||||
@ -293,10 +339,6 @@ struct VSearchConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
VSearchToken::Operator op = VSearchToken::And;
|
VSearchToken::Operator op = VSearchToken::And;
|
||||||
|
|
||||||
// """ to input a ";
|
|
||||||
// && for AND, || for OR;
|
|
||||||
QStringList args = VUtils::parseCombinedArgString(p_keyword);
|
|
||||||
for (auto const & arg : args) {
|
for (auto const & arg : args) {
|
||||||
if (arg == QStringLiteral("&&")) {
|
if (arg == QStringLiteral("&&")) {
|
||||||
op = VSearchToken::And;
|
op = VSearchToken::And;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
|
|
||||||
|
#include "utils/vutils.h"
|
||||||
#include "utils/viconutils.h"
|
#include "utils/viconutils.h"
|
||||||
#include "vnote.h"
|
#include "vnote.h"
|
||||||
#include "vmainwindow.h"
|
#include "vmainwindow.h"
|
||||||
@ -43,7 +44,7 @@ void VSearchResultTree::initActions()
|
|||||||
m_openAct->setToolTip(tr("Open selected notes"));
|
m_openAct->setToolTip(tr("Open selected notes"));
|
||||||
connect(m_openAct, &QAction::triggered,
|
connect(m_openAct, &QAction::triggered,
|
||||||
this, [this]() {
|
this, [this]() {
|
||||||
activateItem(topLevelItem(currentItem()));
|
activateItem(currentItem());
|
||||||
});
|
});
|
||||||
|
|
||||||
m_locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"),
|
m_locateAct = new QAction(VIconUtils::menuIcon(":/resources/icons/locate_note.svg"),
|
||||||
@ -207,7 +208,7 @@ VSearchResultItem::ItemType VSearchResultTree::itemResultType(const QTreeWidgetI
|
|||||||
const QSharedPointer<VSearchResultItem> &VSearchResultTree::itemResultData(const QTreeWidgetItem *p_item) const
|
const QSharedPointer<VSearchResultItem> &VSearchResultTree::itemResultData(const QTreeWidgetItem *p_item) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(p_item);
|
Q_ASSERT(p_item);
|
||||||
const QTreeWidgetItem *topItem = topLevelItem(p_item);
|
const QTreeWidgetItem *topItem = VUtils::topLevelTreeItem(p_item);
|
||||||
int idx = topItem->data(0, Qt::UserRole).toInt();
|
int idx = topItem->data(0, Qt::UserRole).toInt();
|
||||||
Q_ASSERT(idx >= 0 && idx < m_data.size());
|
Q_ASSERT(idx >= 0 && idx < m_data.size());
|
||||||
return m_data[idx];
|
return m_data[idx];
|
||||||
|
@ -39,8 +39,6 @@ private:
|
|||||||
|
|
||||||
VSearchResultItem::ItemType itemResultType(const QTreeWidgetItem *p_item) const;
|
VSearchResultItem::ItemType itemResultType(const QTreeWidgetItem *p_item) const;
|
||||||
|
|
||||||
const QTreeWidgetItem *topLevelItem(const QTreeWidgetItem *p_item) const;
|
|
||||||
|
|
||||||
void activateItem(const QTreeWidgetItem *p_item) const;
|
void activateItem(const QTreeWidgetItem *p_item) const;
|
||||||
|
|
||||||
const QSharedPointer<VSearchResultItem> &itemResultData(const QTreeWidgetItem *p_item) const;
|
const QSharedPointer<VSearchResultItem> &itemResultData(const QTreeWidgetItem *p_item) const;
|
||||||
@ -58,16 +56,4 @@ private:
|
|||||||
QAction *m_addToCartAct;
|
QAction *m_addToCartAct;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const QTreeWidgetItem *VSearchResultTree::topLevelItem(const QTreeWidgetItem *p_item) const
|
|
||||||
{
|
|
||||||
if (!p_item) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_item->parent()) {
|
|
||||||
return p_item->parent();
|
|
||||||
} else {
|
|
||||||
return p_item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // VSEARCHRESULTTREE_H
|
#endif // VSEARCHRESULTTREE_H
|
||||||
|
@ -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,
|
connect(m_listWidget, SIGNAL(itemActivated(QListWidgetItem *)),
|
||||||
this, &VSearchUE::activateItem);
|
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,17 +277,71 @@ 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();
|
||||||
if (++itemAdded >= 10) {
|
} else if (itemAdded >= 20) {
|
||||||
itemAdded = 0;
|
itemAdded = 0;
|
||||||
m_listWidget->updateGeometry();
|
m_listWidget->updateGeometry();
|
||||||
emit widgetUpdated();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
++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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void VSearchUE::handleSearchFinished(const QSharedPointer<VSearchResult> &p_result)
|
void VSearchUE::handleSearchFinished(const QSharedPointer<VSearchResult> &p_result)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_inSearch);
|
Q_ASSERT(m_inSearch);
|
||||||
@ -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();
|
if (finished) {
|
||||||
m_inSearch = false;
|
m_search->clear();
|
||||||
|
m_inSearch = false;
|
||||||
|
}
|
||||||
|
|
||||||
widget(m_id)->updateGeometry();
|
QWidget *wid = widget(m_id);
|
||||||
|
if (wid == m_treeWidget) {
|
||||||
|
m_treeWidget->resizeColumnToContents(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
Q_ASSERT(p_item);
|
||||||
return;
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
emit requestHideUniversalEntry();
|
void VSearchUE::activateItem(const QSharedPointer<VSearchResultItem> &p_item)
|
||||||
|
{
|
||||||
const QSharedPointer<VSearchResultItem> &resItem = itemResultData(p_item);
|
switch (p_item->m_type) {
|
||||||
switch (resItem->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);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
class VListWidgetDoubleRows;
|
class VListWidgetDoubleRows;
|
||||||
class QListWidgetItem;
|
class QListWidgetItem;
|
||||||
|
class VTreeWidget;
|
||||||
|
class QTreeWidgetItem;
|
||||||
|
|
||||||
|
|
||||||
// Universal Entry to list and search all the notebooks.
|
// Universal Entry to list and search all the notebooks.
|
||||||
@ -23,7 +25,10 @@ public:
|
|||||||
Name_Notebook_AllNotebook = 0,
|
Name_Notebook_AllNotebook = 0,
|
||||||
|
|
||||||
// Search the name of the folder/note in all the notebooks.
|
// Search the name of the folder/note in all the notebooks.
|
||||||
Name_FolderNote_AllNotebook
|
Name_FolderNote_AllNotebook,
|
||||||
|
|
||||||
|
// Search content of the note in all the notebooks.
|
||||||
|
Content_Note_AllNotebook,
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit VSearchUE(QObject *p_parent = nullptr);
|
explicit VSearchUE(QObject *p_parent = nullptr);
|
||||||
@ -52,20 +57,30 @@ private slots:
|
|||||||
|
|
||||||
void handleSearchFinished(const QSharedPointer<VSearchResult> &p_result);
|
void handleSearchFinished(const QSharedPointer<VSearchResult> &p_result);
|
||||||
|
|
||||||
|
void activateItem(QListWidgetItem *p_item);
|
||||||
|
|
||||||
|
void activateItem(QTreeWidgetItem *p_item, int p_col);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void searchNameOfAllNotebooks(const QString &p_cmd);
|
void searchNameOfAllNotebooks(const QString &p_cmd);
|
||||||
|
|
||||||
void searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd);
|
void searchNameOfFolderNoteInAllNotebooks(const QString &p_cmd);
|
||||||
|
|
||||||
|
void searchContentOfNoteInAllNotebooks(const QString &p_cmd);
|
||||||
|
|
||||||
// Stop the search synchronously.
|
// Stop the search synchronously.
|
||||||
void stopSearch();
|
void stopSearch();
|
||||||
|
|
||||||
void appendItemToList(const QSharedPointer<VSearchResultItem> &p_item);
|
void appendItemToList(const QSharedPointer<VSearchResultItem> &p_item);
|
||||||
|
|
||||||
void activateItem(const QListWidgetItem *p_item);
|
void appendItemToTree(const QSharedPointer<VSearchResultItem> &p_item);
|
||||||
|
|
||||||
|
void activateItem(const QSharedPointer<VSearchResultItem> &p_item);
|
||||||
|
|
||||||
const QSharedPointer<VSearchResultItem> &itemResultData(const QListWidgetItem *p_item) const;
|
const QSharedPointer<VSearchResultItem> &itemResultData(const QListWidgetItem *p_item) const;
|
||||||
|
|
||||||
|
const QSharedPointer<VSearchResultItem> &itemResultData(const QTreeWidgetItem *p_item) const;
|
||||||
|
|
||||||
VSearch *m_search;
|
VSearch *m_search;
|
||||||
|
|
||||||
bool m_inSearch;
|
bool m_inSearch;
|
||||||
@ -80,6 +95,8 @@ private:
|
|||||||
QIcon m_notebookIcon;
|
QIcon m_notebookIcon;
|
||||||
|
|
||||||
VListWidgetDoubleRows *m_listWidget;
|
VListWidgetDoubleRows *m_listWidget;
|
||||||
|
|
||||||
|
VTreeWidget *m_treeWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VSEARCHUE_H
|
#endif // VSEARCHUE_H
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
VTreeWidget::VTreeWidget(QWidget *p_parent)
|
VTreeWidget::VTreeWidget(QWidget *p_parent)
|
||||||
: QTreeWidget(p_parent),
|
: QTreeWidget(p_parent),
|
||||||
ISimpleSearch()
|
ISimpleSearch(),
|
||||||
|
m_fitContent(false)
|
||||||
{
|
{
|
||||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
|
|
||||||
@ -45,6 +46,13 @@ VTreeWidget::VTreeWidget(QWidget *p_parent)
|
|||||||
|
|
||||||
m_delegate = new VStyledItemDelegate(this);
|
m_delegate = new VStyledItemDelegate(this);
|
||||||
setItemDelegate(m_delegate);
|
setItemDelegate(m_delegate);
|
||||||
|
|
||||||
|
connect(this, &VTreeWidget::itemExpanded,
|
||||||
|
this, [this]() {
|
||||||
|
if (m_fitContent) {
|
||||||
|
resizeColumnToContents(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VTreeWidget::keyPressEvent(QKeyEvent *p_event)
|
void VTreeWidget::keyPressEvent(QKeyEvent *p_event)
|
||||||
@ -288,26 +296,32 @@ void VTreeWidget::selectNextItem(bool p_forward)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QTreeWidgetItem *nextItem = NULL;
|
QTreeWidgetItem *nItem = nextItem(item, p_forward);
|
||||||
|
if (nItem) {
|
||||||
|
setCurrentItem(nItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeWidgetItem *VTreeWidget::nextItem(QTreeWidgetItem *p_item, bool p_forward)
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *nItem = NULL;
|
||||||
if (p_forward) {
|
if (p_forward) {
|
||||||
if (item->isExpanded()) {
|
if (p_item->isExpanded()) {
|
||||||
nextItem = item->child(0);
|
nItem = p_item->child(0);
|
||||||
} else {
|
} else {
|
||||||
while (!nextItem && item) {
|
while (!nItem && p_item) {
|
||||||
nextItem = nextSibling(item, true);
|
nItem = nextSibling(p_item, true);
|
||||||
item = item->parent();
|
p_item = p_item->parent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
nextItem = nextSibling(item, false);
|
nItem = nextSibling(p_item, false);
|
||||||
if (!nextItem) {
|
if (!nItem) {
|
||||||
nextItem = item->parent();
|
nItem = p_item->parent();
|
||||||
} else {
|
} else {
|
||||||
nextItem = lastItemOfTree(nextItem);
|
nItem = lastItemOfTree(nItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextItem) {
|
return nItem;
|
||||||
setCurrentItem(nextItem);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
|
|
||||||
virtual void selectNextItem(bool p_forward) Q_DECL_OVERRIDE;
|
virtual void selectNextItem(bool p_forward) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
void setFitContent(bool p_enabled);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
@ -63,11 +65,16 @@ private:
|
|||||||
|
|
||||||
QTreeWidgetItem *nextSibling(QTreeWidgetItem *p_item, bool p_forward);
|
QTreeWidgetItem *nextSibling(QTreeWidgetItem *p_item, bool p_forward);
|
||||||
|
|
||||||
|
// Next visible item.
|
||||||
|
QTreeWidgetItem *nextItem(QTreeWidgetItem *p_item, bool p_forward);
|
||||||
|
|
||||||
VSimpleSearchInput *m_searchInput;
|
VSimpleSearchInput *m_searchInput;
|
||||||
|
|
||||||
VStyledItemDelegate *m_delegate;
|
VStyledItemDelegate *m_delegate;
|
||||||
|
|
||||||
QTimer *m_searchColdTimer;
|
QTimer *m_searchColdTimer;
|
||||||
|
|
||||||
|
bool m_fitContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void VTreeWidget::setSimpleSearchMatchFlags(Qt::MatchFlags p_flags)
|
inline void VTreeWidget::setSimpleSearchMatchFlags(Qt::MatchFlags p_flags)
|
||||||
@ -79,4 +86,11 @@ inline Qt::MatchFlags VTreeWidget::getSimpleSearchMatchFlags() const
|
|||||||
{
|
{
|
||||||
return m_searchInput->getMatchFlags();
|
return m_searchInput->getMatchFlags();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void VTreeWidget::setFitContent(bool p_enabled)
|
||||||
|
{
|
||||||
|
m_fitContent = p_enabled;
|
||||||
|
setSizeAdjustPolicy(m_fitContent ? QAbstractScrollArea::AdjustToContents
|
||||||
|
: QAbstractScrollArea::AdjustIgnored);
|
||||||
|
}
|
||||||
#endif // VTREEWIDGET_H
|
#endif // VTREEWIDGET_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user