mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 05:49:53 +08:00
Editor: highlight matches of full-text search result in page
This commit is contained in:
parent
647807a918
commit
a055d6e935
@ -62,6 +62,7 @@ VSettingsDialog::VSettingsDialog(QWidget *p_parent)
|
||||
addTab(new VReadEditTab(), tr("Read/Edit"));
|
||||
addTab(new VNoteManagementTab(), tr("Note Management"));
|
||||
addTab(new VMarkdownTab(), tr("Markdown"));
|
||||
addTab(new VMiscTab(), tr("Misc"));
|
||||
|
||||
m_tabList->setMaximumWidth(m_tabList->sizeHintForColumn(0) + 5);
|
||||
|
||||
@ -193,6 +194,15 @@ void VSettingsDialog::loadConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
// Misc Tab.
|
||||
{
|
||||
VMiscTab *miscTab = dynamic_cast<VMiscTab *>(m_tabs->widget(idx++));
|
||||
Q_ASSERT(miscTab);
|
||||
if (!miscTab->loadConfiguration()) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
err:
|
||||
VUtils::showMessage(QMessageBox::Warning, tr("Warning"),
|
||||
@ -249,6 +259,15 @@ void VSettingsDialog::saveConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
// Misc Tab.
|
||||
{
|
||||
VMiscTab *miscTab = dynamic_cast<VMiscTab *>(m_tabs->widget(idx++));
|
||||
Q_ASSERT(miscTab);
|
||||
if (!miscTab->saveConfiguration()) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
accept();
|
||||
return;
|
||||
err:
|
||||
@ -1354,3 +1373,45 @@ bool VMarkdownTab::saveGraphviz()
|
||||
g_config->setGraphvizDot(m_graphvizDotEdit->text());
|
||||
return true;
|
||||
}
|
||||
|
||||
VMiscTab::VMiscTab(QWidget *p_parent)
|
||||
: QWidget(p_parent)
|
||||
{
|
||||
m_matchesInPageCB = new QCheckBox(tr("Highlight matches of a full-text search in page"),
|
||||
this);
|
||||
|
||||
QFormLayout *mainLayout = new QFormLayout();
|
||||
mainLayout->addRow(m_matchesInPageCB);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
||||
bool VMiscTab::loadConfiguration()
|
||||
{
|
||||
if (!loadMatchesInPage()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VMiscTab::saveConfiguration()
|
||||
{
|
||||
if (!saveMatchesInPage()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VMiscTab::loadMatchesInPage()
|
||||
{
|
||||
m_matchesInPageCB->setChecked(g_config->getHighlightMatchesInPage());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VMiscTab::saveMatchesInPage()
|
||||
{
|
||||
g_config->setHighlightMatchesInPage(m_matchesInPageCB->isChecked());
|
||||
return true;
|
||||
}
|
||||
|
@ -227,6 +227,22 @@ private:
|
||||
VLineEdit *m_graphvizDotEdit;
|
||||
};
|
||||
|
||||
class VMiscTab : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VMiscTab(QWidget *p_parent = 0);
|
||||
bool loadConfiguration();
|
||||
bool saveConfiguration();
|
||||
|
||||
private:
|
||||
bool loadMatchesInPage();
|
||||
bool saveMatchesInPage();
|
||||
|
||||
// Highlight matches in page.
|
||||
QCheckBox *m_matchesInPageCB;
|
||||
};
|
||||
|
||||
class VSettingsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -262,6 +262,9 @@ multiple_keyboard_layout=true
|
||||
; Whether insert new note in front
|
||||
insert_new_note_in_front=false
|
||||
|
||||
; Whether highlight matches in page when activating a search result item
|
||||
highlight_matches_in_page=true
|
||||
|
||||
[editor]
|
||||
; Auto indent as previous line
|
||||
auto_indent=true
|
||||
|
@ -1526,12 +1526,21 @@ const QTreeWidgetItem *VUtils::topLevelTreeItem(const QTreeWidgetItem *p_item)
|
||||
}
|
||||
|
||||
if (p_item->parent()) {
|
||||
return p_item->parent();
|
||||
return topLevelTreeItem(p_item->parent());
|
||||
} else {
|
||||
return p_item;
|
||||
}
|
||||
}
|
||||
|
||||
int VUtils::childIndexOfTreeItem(const QTreeWidgetItem *p_item)
|
||||
{
|
||||
if (p_item->parent()) {
|
||||
return p_item->parent()->indexOfChild(const_cast<QTreeWidgetItem *>(p_item));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
QImage VUtils::imageFromFile(const QString &p_filePath)
|
||||
{
|
||||
QImage img;
|
||||
|
@ -333,6 +333,8 @@ public:
|
||||
|
||||
static const QTreeWidgetItem *topLevelTreeItem(const QTreeWidgetItem *p_item);
|
||||
|
||||
static int childIndexOfTreeItem(const QTreeWidgetItem *p_item);
|
||||
|
||||
// Read QImage from local file @p_filePath.
|
||||
// Directly calling QImage(p_filePath) will judge the image format from the suffix,
|
||||
// resulting a null image in wrong suffix case.
|
||||
|
@ -320,6 +320,9 @@ void VConfigManager::initialize()
|
||||
m_insertNewNoteInFront = getConfigFromSettings("global",
|
||||
"insert_new_note_in_front").toBool();
|
||||
|
||||
m_highlightMatchesInPage = getConfigFromSettings("global",
|
||||
"highlight_matches_in_page").toBool();
|
||||
|
||||
initEditorConfigs();
|
||||
}
|
||||
|
||||
|
@ -484,6 +484,9 @@ public:
|
||||
const QString &getQuickAccess() const;
|
||||
void setQuickAccess(const QString &p_path);
|
||||
|
||||
bool getHighlightMatchesInPage() const;
|
||||
void setHighlightMatchesInPage(bool p_enabled);
|
||||
|
||||
// All the themes.
|
||||
QList<QString> getThemes() const;
|
||||
|
||||
@ -923,6 +926,9 @@ private:
|
||||
// Absolute path of quick access note.
|
||||
QString m_quickAccess;
|
||||
|
||||
// Whether highlight matches in page when activating a search item.
|
||||
bool m_highlightMatchesInPage;
|
||||
|
||||
// The theme name.
|
||||
QString m_theme;
|
||||
|
||||
@ -2613,4 +2619,19 @@ inline void VConfigManager::setQuickAccess(const QString &p_path)
|
||||
m_quickAccess = p_path;
|
||||
setConfigToSettings("global", "quick_access", m_quickAccess);
|
||||
}
|
||||
|
||||
inline bool VConfigManager::getHighlightMatchesInPage() const
|
||||
{
|
||||
return m_highlightMatchesInPage;
|
||||
}
|
||||
|
||||
inline void VConfigManager::setHighlightMatchesInPage(bool p_enabled)
|
||||
{
|
||||
if (m_highlightMatchesInPage == p_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_highlightMatchesInPage = p_enabled;
|
||||
setConfigToSettings("global", "highlight_matches_in_page", m_highlightMatchesInPage);
|
||||
}
|
||||
#endif // VCONFIGMANAGER_H
|
||||
|
126
src/veditor.cpp
126
src/veditor.cpp
@ -371,6 +371,69 @@ QList<QTextCursor> VEditor::findTextAll(const QString &p_text,
|
||||
return results;
|
||||
}
|
||||
|
||||
static void mergeResult(QList<QTextCursor> &p_result, const QList<QTextCursor> &p_part)
|
||||
{
|
||||
if (p_result.isEmpty()) {
|
||||
p_result = p_part;
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = 0;
|
||||
for (auto const & cur : p_part) {
|
||||
// Find position to insert into @p_result.
|
||||
while (idx < p_result.size()) {
|
||||
const QTextCursor &toCur = p_result[idx];
|
||||
if (cur.selectionEnd() <= toCur.selectionStart()) {
|
||||
// Insert it before toCur.
|
||||
p_result.insert(idx, cur);
|
||||
++idx;
|
||||
break;
|
||||
} else if (cur.selectionStart() < toCur.selectionEnd()) {
|
||||
// Interleave. Abandon it.
|
||||
break;
|
||||
} else {
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
||||
// Insert to the end.
|
||||
if (idx >= p_result.size()) {
|
||||
p_result.append(cur);
|
||||
idx = p_result.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<QTextCursor> VEditor::findTextAll(const VSearchToken &p_token,
|
||||
int p_start,
|
||||
int p_end)
|
||||
{
|
||||
QList<QTextCursor> results;
|
||||
if (p_token.isEmpty()) {
|
||||
return results;
|
||||
}
|
||||
|
||||
QTextDocument::FindFlags flags;
|
||||
if (p_token.m_caseSensitivity == Qt::CaseSensitive) {
|
||||
flags |= QTextDocument::FindCaseSensitively;
|
||||
}
|
||||
|
||||
if (p_token.m_type == VSearchToken::RawString) {
|
||||
for (auto const & wd : p_token.m_keywords) {
|
||||
QList<QTextCursor> part = findTextAllInRange(m_document, wd, flags, p_start, p_end);
|
||||
mergeResult(results, part);
|
||||
}
|
||||
} else {
|
||||
// Regular expression.
|
||||
for (auto const & reg : p_token.m_regs) {
|
||||
QList<QTextCursor> part = findTextAllInRange(m_document, reg, flags, p_start, p_end);
|
||||
mergeResult(results, part);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
const QList<QTextCursor> &VEditor::findTextAllCached(const QString &p_text,
|
||||
uint p_options,
|
||||
int p_start,
|
||||
@ -391,6 +454,25 @@ const QList<QTextCursor> &VEditor::findTextAllCached(const QString &p_text,
|
||||
return m_findInfo.m_result;
|
||||
}
|
||||
|
||||
const QList<QTextCursor> &VEditor::findTextAllCached(const VSearchToken &p_token,
|
||||
int p_start,
|
||||
int p_end)
|
||||
{
|
||||
if (p_token.isEmpty()) {
|
||||
m_findInfo.clear();
|
||||
return m_findInfo.m_result;
|
||||
}
|
||||
|
||||
if (m_findInfo.isCached(p_token, p_start, p_end)) {
|
||||
return m_findInfo.m_result;
|
||||
}
|
||||
|
||||
QList<QTextCursor> result = findTextAll(p_token, p_start, p_end);
|
||||
m_findInfo.update(p_token, p_start, p_end, result);
|
||||
|
||||
return m_findInfo.m_result;
|
||||
}
|
||||
|
||||
void VEditor::highlightSelectedWord()
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> &selects = m_extraSelections[(int)SelectionId::SelectedWord];
|
||||
@ -613,6 +695,48 @@ bool VEditor::findText(const QString &p_text,
|
||||
p_useLeftSideOfCursor);
|
||||
}
|
||||
|
||||
bool VEditor::findText(const VSearchToken &p_token, bool p_forward, bool p_fromStart)
|
||||
{
|
||||
clearIncrementalSearchedWordHighlight();
|
||||
|
||||
if (p_token.isEmpty()) {
|
||||
m_findInfo.clear();
|
||||
clearSearchedWordHighlight();
|
||||
return false;
|
||||
}
|
||||
|
||||
const QList<QTextCursor> &result = findTextAllCached(p_token);
|
||||
|
||||
if (result.isEmpty()) {
|
||||
clearSearchedWordHighlight();
|
||||
|
||||
emit m_object->statusMessage(QObject::tr("No match found"));
|
||||
} else {
|
||||
// Locate to the right match and update current cursor.
|
||||
QTextCursor cursor = textCursorW();
|
||||
int pos = p_fromStart ? (m_document->characterCount() + 1) : cursor.position();
|
||||
bool wrapped = false;
|
||||
int idx = selectCursor(result, pos, p_forward, wrapped);
|
||||
const QTextCursor &tcursor = result.at(idx);
|
||||
if (wrapped && !p_fromStart) {
|
||||
showWrapLabel();
|
||||
}
|
||||
|
||||
cursor.setPosition(tcursor.selectionStart(), QTextCursor::MoveAnchor);
|
||||
setTextCursorW(cursor);
|
||||
|
||||
highlightSearchedWord(result);
|
||||
|
||||
highlightSearchedWordUnderCursor(tcursor);
|
||||
|
||||
emit m_object->statusMessage(QObject::tr("Match found: %2 of %3")
|
||||
.arg(idx + 1)
|
||||
.arg(result.size()));
|
||||
}
|
||||
|
||||
return !result.isEmpty();
|
||||
}
|
||||
|
||||
bool VEditor::findTextInRange(const QString &p_text,
|
||||
uint p_options,
|
||||
bool p_forward,
|
||||
@ -1463,7 +1587,7 @@ void VEditor::nextMatch(bool p_forward)
|
||||
}
|
||||
|
||||
if (m_findInfo.m_useToken) {
|
||||
// TODO
|
||||
findText(m_findInfo.m_token, p_forward, false);
|
||||
} else {
|
||||
findTextInRange(m_findInfo.m_text,
|
||||
m_findInfo.m_options,
|
||||
|
@ -84,6 +84,8 @@ public:
|
||||
QTextCursor::MoveMode p_moveMode = QTextCursor::MoveAnchor,
|
||||
bool p_useLeftSideOfCursor = false);
|
||||
|
||||
bool findText(const VSearchToken &p_token, bool p_forward, bool p_fromStart);
|
||||
|
||||
// Constrain the scope.
|
||||
bool findTextInRange(const QString &p_text,
|
||||
uint p_options,
|
||||
@ -327,6 +329,17 @@ private:
|
||||
&& m_end == p_end;
|
||||
}
|
||||
|
||||
bool isCached(const VSearchToken &p_token,
|
||||
int p_start = 0,
|
||||
int p_end = -1) const
|
||||
{
|
||||
return m_cacheValid
|
||||
&& m_useToken
|
||||
&& m_token == p_token
|
||||
&& m_start == p_start
|
||||
&& m_end == p_end;
|
||||
}
|
||||
|
||||
void update(const QString &p_text,
|
||||
uint p_options,
|
||||
int p_start,
|
||||
@ -347,10 +360,29 @@ private:
|
||||
m_token.clear();
|
||||
}
|
||||
|
||||
void update(const VSearchToken &p_token,
|
||||
int p_start,
|
||||
int p_end,
|
||||
const QList<QTextCursor> &p_result)
|
||||
{
|
||||
m_start = p_start;
|
||||
m_end = p_end;
|
||||
|
||||
m_useToken = true;
|
||||
|
||||
m_token = p_token;
|
||||
|
||||
m_cacheValid = true;
|
||||
m_result = p_result;
|
||||
|
||||
m_text.clear();
|
||||
m_options = 0;
|
||||
}
|
||||
|
||||
bool isNull() const
|
||||
{
|
||||
if (m_useToken) {
|
||||
return m_token.tokenSize() == 0;
|
||||
return m_token.isEmpty();
|
||||
} else {
|
||||
return m_text.isEmpty();
|
||||
}
|
||||
@ -396,11 +428,19 @@ private:
|
||||
int p_start = 0,
|
||||
int p_end = -1);
|
||||
|
||||
QList<QTextCursor> findTextAll(const VSearchToken &p_token,
|
||||
int p_start = 0,
|
||||
int p_end = -1);
|
||||
|
||||
const QList<QTextCursor> &findTextAllCached(const QString &p_text,
|
||||
uint p_options,
|
||||
int p_start = 0,
|
||||
int p_end = -1);
|
||||
|
||||
const QList<QTextCursor> &findTextAllCached(const VSearchToken &p_token,
|
||||
int p_start = 0,
|
||||
int p_end = -1);
|
||||
|
||||
// Highlight @p_cursor as the incremental searched keyword.
|
||||
void highlightIncrementalSearchedWord(const QTextCursor &p_cursor);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "utils/vvim.h"
|
||||
#include "vedittabinfo.h"
|
||||
#include "vwordcountinfo.h"
|
||||
#include "vsearchconfig.h"
|
||||
|
||||
class VEditArea;
|
||||
class VSnippet;
|
||||
@ -59,6 +60,10 @@ public:
|
||||
virtual void findText(const QString &p_text, uint p_options, bool p_peek,
|
||||
bool p_forward = true) = 0;
|
||||
|
||||
virtual void findText(const VSearchToken &p_token,
|
||||
bool p_forward = true,
|
||||
bool p_fromStart = false) = 0;
|
||||
|
||||
// Replace @p_text with @p_replaceText in current note.
|
||||
virtual void replaceText(const QString &p_text, uint p_options,
|
||||
const QString &p_replaceText, bool p_findNext) = 0;
|
||||
|
@ -224,6 +224,17 @@ void VHtmlTab::findText(const QString &p_text, uint p_options, bool p_peek,
|
||||
}
|
||||
}
|
||||
|
||||
void VHtmlTab::findText(const VSearchToken &p_token,
|
||||
bool p_forward,
|
||||
bool p_fromStart)
|
||||
{
|
||||
// TODO
|
||||
Q_UNUSED(p_token);
|
||||
Q_UNUSED(p_forward);
|
||||
Q_UNUSED(p_fromStart);
|
||||
return;
|
||||
}
|
||||
|
||||
void VHtmlTab::replaceText(const QString &p_text, uint p_options,
|
||||
const QString &p_replaceText, bool p_findNext)
|
||||
{
|
||||
|
@ -34,6 +34,10 @@ public:
|
||||
void findText(const QString &p_text, uint p_options, bool p_peek,
|
||||
bool p_forward = true) Q_DECL_OVERRIDE;
|
||||
|
||||
void findText(const VSearchToken &p_token,
|
||||
bool p_forward = true,
|
||||
bool p_fromStart = false) Q_DECL_OVERRIDE;
|
||||
|
||||
// Replace @p_text with @p_replaceText in current note.
|
||||
void replaceText(const QString &p_text, uint p_options,
|
||||
const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE;
|
||||
|
@ -701,6 +701,18 @@ void VMdTab::findText(const QString &p_text, uint p_options, bool p_peek,
|
||||
}
|
||||
}
|
||||
|
||||
void VMdTab::findText(const VSearchToken &p_token,
|
||||
bool p_forward,
|
||||
bool p_fromStart)
|
||||
{
|
||||
if (m_isEditMode) {
|
||||
m_editor->findText(p_token, p_forward, p_fromStart);
|
||||
} else {
|
||||
// TODO
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
void VMdTab::replaceText(const QString &p_text, uint p_options,
|
||||
const QString &p_replaceText, bool p_findNext)
|
||||
{
|
||||
|
@ -50,6 +50,10 @@ public:
|
||||
void findText(const QString &p_text, uint p_options, bool p_peek,
|
||||
bool p_forward = true) Q_DECL_OVERRIDE;
|
||||
|
||||
void findText(const VSearchToken &p_token,
|
||||
bool p_forward = true,
|
||||
bool p_fromStart = false) Q_DECL_OVERRIDE;
|
||||
|
||||
// Replace @p_text with @p_replaceText in current note.
|
||||
void replaceText(const QString &p_text, uint p_options,
|
||||
const QString &p_replaceText, bool p_findNext) Q_DECL_OVERRIDE;
|
||||
|
@ -487,7 +487,8 @@ VSearchResultItem *VSearch::searchForOutline(const VFile *p_file) const
|
||||
item = new VSearchResultItem(VSearchResultItem::Note,
|
||||
VSearchResultItem::OutlineIndex,
|
||||
p_file->getName(),
|
||||
p_file->fetchPath());
|
||||
p_file->fetchPath(),
|
||||
m_config);
|
||||
}
|
||||
|
||||
VSearchResultSubItem sitem(it.m_index, it.m_name);
|
||||
@ -600,7 +601,8 @@ VSearchResultItem *VSearch::searchForContent(const VFile *p_file) const
|
||||
item = new VSearchResultItem(VSearchResultItem::Note,
|
||||
VSearchResultItem::LineNumber,
|
||||
p_file->getName(),
|
||||
p_file->fetchPath());
|
||||
p_file->fetchPath(),
|
||||
m_config);
|
||||
}
|
||||
|
||||
VSearchResultSubItem sitem(lineNum, lineText);
|
||||
|
@ -165,6 +165,26 @@ struct VSearchToken
|
||||
return m_type == Type::RawString ? m_keywords.size() : m_regs.size();
|
||||
}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
return tokenSize() == 0;
|
||||
}
|
||||
|
||||
bool operator==(const VSearchToken &p_other) const
|
||||
{
|
||||
if (m_type != p_other.m_type
|
||||
|| m_op != p_other.m_op
|
||||
|| m_caseSensitivity != p_other.m_caseSensitivity
|
||||
|| m_keywords.size() != p_other.m_keywords.size()
|
||||
|| m_numOfMatches != p_other.m_numOfMatches
|
||||
|| m_regs.size() != p_other.m_regs.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_keywords == p_other.m_keywords
|
||||
&& m_regs == p_other.m_regs;
|
||||
}
|
||||
|
||||
VSearchToken::Type m_type;
|
||||
|
||||
VSearchToken::Operator m_op;
|
||||
@ -484,11 +504,13 @@ struct VSearchResultItem
|
||||
VSearchResultItem(VSearchResultItem::ItemType p_type,
|
||||
VSearchResultItem::MatchType p_matchType,
|
||||
const QString &p_text,
|
||||
const QString &p_path)
|
||||
const QString &p_path,
|
||||
const QSharedPointer<VSearchConfig> &p_config = nullptr)
|
||||
: m_type(p_type),
|
||||
m_matchType(p_matchType),
|
||||
m_text(p_text),
|
||||
m_path(p_path)
|
||||
m_path(p_path),
|
||||
m_config(p_config)
|
||||
{
|
||||
}
|
||||
|
||||
@ -518,6 +540,9 @@ struct VSearchResultItem
|
||||
|
||||
// Matched places within this item.
|
||||
QList<VSearchResultSubItem> m_matches;
|
||||
|
||||
// Search config to search for this item.
|
||||
QSharedPointer<VSearchConfig> m_config;
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,10 +14,12 @@ VSearchEngineWorker::VSearchEngineWorker(QObject *p_parent)
|
||||
}
|
||||
|
||||
void VSearchEngineWorker::setData(const QStringList &p_files,
|
||||
const VSearchToken &p_token)
|
||||
const VSearchToken &p_token,
|
||||
const QSharedPointer<VSearchConfig> &p_config)
|
||||
{
|
||||
m_files = p_files;
|
||||
m_token = p_token;
|
||||
m_config = p_config;
|
||||
}
|
||||
|
||||
void VSearchEngineWorker::stop()
|
||||
@ -104,7 +106,8 @@ VSearchResultItem *VSearchEngineWorker::searchFile(const QString &p_fileName)
|
||||
item = new VSearchResultItem(VSearchResultItem::Note,
|
||||
VSearchResultItem::LineNumber,
|
||||
VUtils::fileNameFromPath(p_fileName),
|
||||
p_fileName);
|
||||
p_fileName,
|
||||
m_config);
|
||||
}
|
||||
|
||||
VSearchResultSubItem sitem(lineNum, line);
|
||||
@ -188,7 +191,8 @@ void VSearchEngine::search(const QSharedPointer<VSearchConfig> &p_config,
|
||||
|
||||
VSearchEngineWorker *th = new VSearchEngineWorker(this);
|
||||
th->setData(m_result->m_secondPhaseItems.mid(start, len),
|
||||
p_config->m_contentToken);
|
||||
p_config->m_contentToken,
|
||||
p_config);
|
||||
connect(th, &VSearchEngineWorker::finished,
|
||||
this, &VSearchEngine::handleWorkerFinished);
|
||||
connect(th, &VSearchEngineWorker::resultItemsReady,
|
||||
|
@ -22,7 +22,8 @@ public:
|
||||
explicit VSearchEngineWorker(QObject *p_parent = nullptr);
|
||||
|
||||
void setData(const QStringList &p_files,
|
||||
const VSearchToken &p_token);
|
||||
const VSearchToken &p_token,
|
||||
const QSharedPointer<VSearchConfig> &p_config);
|
||||
|
||||
public slots:
|
||||
void stop();
|
||||
@ -46,6 +47,8 @@ private:
|
||||
|
||||
VSearchToken m_token;
|
||||
|
||||
QSharedPointer<VSearchConfig> m_config;
|
||||
|
||||
VSearchState m_state;
|
||||
|
||||
QString m_error;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "vhistorylist.h"
|
||||
#include "vexplorer.h"
|
||||
#include "vuniversalentry.h"
|
||||
#include "vsearchue.h"
|
||||
|
||||
extern VNote *g_vnote;
|
||||
|
||||
@ -268,40 +269,5 @@ void VSearchResultTree::activateItem(const QTreeWidgetItem *p_item) const
|
||||
return;
|
||||
}
|
||||
|
||||
const QSharedPointer<VSearchResultItem> &resItem = itemResultData(p_item);
|
||||
switch (resItem->m_type) {
|
||||
case VSearchResultItem::Note:
|
||||
{
|
||||
QStringList files(resItem->m_path);
|
||||
g_mainWin->openFiles(files);
|
||||
break;
|
||||
}
|
||||
|
||||
case VSearchResultItem::Folder:
|
||||
{
|
||||
VDirectory *dir = g_vnote->getInternalDirectory(resItem->m_path);
|
||||
if (dir) {
|
||||
g_mainWin->locateDirectory(dir);
|
||||
} else {
|
||||
// External directory.
|
||||
g_mainWin->showExplorerPanel(true);
|
||||
g_mainWin->getExplorer()->setRootDirectory(resItem->m_path);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case VSearchResultItem::Notebook:
|
||||
{
|
||||
VNotebook *nb = g_vnote->getNotebook(resItem->m_path);
|
||||
if (nb) {
|
||||
g_mainWin->locateNotebook(nb);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
VSearchUE::activateItem(itemResultData(p_item), VUtils::childIndexOfTreeItem(p_item));
|
||||
}
|
||||
|
@ -18,11 +18,14 @@
|
||||
#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)
|
||||
@ -908,13 +911,47 @@ const QSharedPointer<VSearchResultItem> &VSearchUE::itemResultData(const QTreeWi
|
||||
return m_data[idx];
|
||||
}
|
||||
|
||||
void VSearchUE::activateItem(const QSharedPointer<VSearchResultItem> &p_item)
|
||||
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);
|
||||
g_mainWin->openFiles(files);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -923,6 +960,10 @@ void VSearchUE::activateItem(const QSharedPointer<VSearchResultItem> &p_item)
|
||||
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;
|
||||
@ -961,7 +1002,7 @@ void VSearchUE::activateItem(QTreeWidgetItem *p_item, int p_col)
|
||||
}
|
||||
|
||||
emit requestHideUniversalEntry();
|
||||
activateItem(itemResultData(p_item));
|
||||
activateItem(itemResultData(p_item), VUtils::childIndexOfTreeItem(p_item));
|
||||
}
|
||||
|
||||
void VSearchUE::selectNextItem(int p_id, bool p_forward)
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
|
||||
QString currentItemFolder(int p_id) Q_DECL_OVERRIDE;
|
||||
|
||||
static void activateItem(const QSharedPointer<VSearchResultItem> &p_item);
|
||||
static void activateItem(const QSharedPointer<VSearchResultItem> &p_item, int p_matchIndex = 0);
|
||||
|
||||
protected:
|
||||
void init() Q_DECL_OVERRIDE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user