work save: view models for "find in files"
This commit is contained in:
parent
2be69f0758
commit
579b36ff49
|
@ -62,7 +62,8 @@ SOURCES += \
|
|||
widgets/issuestable.cpp \
|
||||
widgets/qconsole.cpp \
|
||||
widgets/qpatchedcombobox.cpp \
|
||||
widgets/searchdialog.cpp
|
||||
widgets/searchdialog.cpp \
|
||||
widgets/searchresultview.cpp
|
||||
|
||||
HEADERS += \
|
||||
HighlighterManager.h \
|
||||
|
@ -119,7 +120,8 @@ HEADERS += \
|
|||
widgets/issuestable.h \
|
||||
widgets/qconsole.h \
|
||||
widgets/qpatchedcombobox.h \
|
||||
widgets/searchdialog.h
|
||||
widgets/searchdialog.h \
|
||||
widgets/searchresultview.h
|
||||
|
||||
FORMS += \
|
||||
settingsdialog/debuggeneralwidget.ui \
|
||||
|
|
|
@ -24,7 +24,7 @@ int SynSearch::resultCount()
|
|||
return mResults.count();
|
||||
}
|
||||
|
||||
int SynSearch::findAll(const QString &newText)
|
||||
int SynSearch::findAll(const QString &keyword)
|
||||
{
|
||||
mResults.clear();
|
||||
if (pattern().isEmpty())
|
||||
|
@ -33,18 +33,18 @@ int SynSearch::findAll(const QString &newText)
|
|||
int next=-1;
|
||||
while (true) {
|
||||
if (options().testFlag(ssoMatchCase)) {
|
||||
next = newText.indexOf(pattern(),start,Qt::CaseSensitive);
|
||||
next = keyword.indexOf(pattern(),start,Qt::CaseSensitive);
|
||||
} else {
|
||||
next = newText.indexOf(pattern(),start,Qt::CaseInsensitive);
|
||||
next = keyword.indexOf(pattern(),start,Qt::CaseInsensitive);
|
||||
}
|
||||
if (next<0) {
|
||||
break;
|
||||
}
|
||||
start = next + newText.length();
|
||||
start = next + keyword.length();
|
||||
if (options().testFlag(ssoWholeWord)) {
|
||||
if (((next<=0) || isDelimitChar(newText[next-1]))
|
||||
if (((next<=0) || isDelimitChar(keyword[next-1]))
|
||||
&&
|
||||
( (start>=newText.length()) || isDelimitChar(newText[start]) )
|
||||
( (start>=keyword.length()) || isDelimitChar(keyword[start]) )
|
||||
) {
|
||||
mResults.append(next);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public:
|
|||
int length(int aIndex) override;
|
||||
int result(int aIndex) override;
|
||||
int resultCount() override;
|
||||
int findAll(const QString &newText) override;
|
||||
int findAll(const QString &keyword) override;
|
||||
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
||||
private:
|
||||
bool isDelimitChar(QChar ch);
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
virtual int length(int aIndex) = 0;
|
||||
virtual int result(int aIndex) = 0;
|
||||
virtual int resultCount() = 0;
|
||||
virtual int findAll(const QString& newText) = 0;
|
||||
virtual int findAll(const QString& keyword) = 0;
|
||||
virtual QString replace(const QString& aOccurrence, const QString& aReplacement) = 0;
|
||||
SynSearchOptions options() const;
|
||||
virtual void setOptions(const SynSearchOptions &options);
|
||||
|
|
|
@ -26,13 +26,13 @@ int SynSearchRegex::resultCount()
|
|||
return mResults.size();
|
||||
}
|
||||
|
||||
int SynSearchRegex::findAll(const QString &newText)
|
||||
int SynSearchRegex::findAll(const QString &keyword)
|
||||
{
|
||||
if (pattern().isEmpty())
|
||||
return 0;
|
||||
mResults.clear();
|
||||
mLengths.clear();
|
||||
QRegularExpressionMatchIterator it = mRegex.globalMatch(newText);
|
||||
QRegularExpressionMatchIterator it = mRegex.globalMatch(keyword);
|
||||
while (it.hasNext()) {
|
||||
QRegularExpressionMatch match = it.next();
|
||||
mLengths.append(match.capturedLength());
|
||||
|
|
|
@ -15,7 +15,7 @@ public:
|
|||
int length(int aIndex) override;
|
||||
int result(int aIndex) override;
|
||||
int resultCount() override;
|
||||
int findAll(const QString &newText) override;
|
||||
int findAll(const QString &keyword) override;
|
||||
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
||||
void setPattern(const QString &value) override;
|
||||
void setOptions(const SynSearchOptions &options) override;
|
||||
|
|
|
@ -34,6 +34,12 @@ enum class FileEndingType {
|
|||
Mac
|
||||
};// Windows: CRLF, UNIX: LF, Mac: CR
|
||||
|
||||
enum class SearchFileScope {
|
||||
currentFile,
|
||||
wholeProject,
|
||||
openedFiles
|
||||
};
|
||||
|
||||
class BaseError{
|
||||
public:
|
||||
explicit BaseError(const QString& reason);
|
||||
|
|
|
@ -260,7 +260,7 @@
|
|||
<item>
|
||||
<widget class="QRadioButton" name="rbCurrentFile">
|
||||
<property name="text">
|
||||
<string>current file</string>
|
||||
<string>Current File</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
|
@ -270,14 +270,14 @@
|
|||
<item>
|
||||
<widget class="QRadioButton" name="rbProject">
|
||||
<property name="text">
|
||||
<string>Files In project</string>
|
||||
<string>Files In Project</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbOpenFiles">
|
||||
<property name="text">
|
||||
<string>Open files</string>
|
||||
<string>Open Files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
#include "searchresultview.h"
|
||||
|
||||
PSearchResults SearchResultModel::addSearchResults(const QString &keyword, SynSearchOptions options, SearchFileScope scope)
|
||||
{
|
||||
int index=-1;
|
||||
for (int i=0;i<mSearchResults.size();i++) {
|
||||
PSearchResults results = mSearchResults[i];
|
||||
if (results->keyword == keyword && results->scope == scope) {
|
||||
index=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index>0) {
|
||||
mSearchResults.removeAt(index);
|
||||
}
|
||||
if (mSearchResults.size()>=MAX_SEARCH_RESULTS) {
|
||||
mSearchResults.pop_back();
|
||||
}
|
||||
PSearchResults results = std::make_shared<SearchResults>();
|
||||
results->keyword = keyword;
|
||||
results->options = options;
|
||||
results->scope = scope;
|
||||
mSearchResults.push_front(results);
|
||||
emit modelChanged();
|
||||
return results;
|
||||
}
|
||||
|
||||
PSearchResults SearchResultModel::results(int index)
|
||||
{
|
||||
if (index<0 || index>=mSearchResults.size()) {
|
||||
return PSearchResults();
|
||||
}
|
||||
return mSearchResults[index];
|
||||
}
|
||||
|
||||
SearchResultModel::SearchResultModel(QObject* parent):
|
||||
QObject(parent),
|
||||
mCurrentIndex(-1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int SearchResultModel::currentIndex() const
|
||||
{
|
||||
return mCurrentIndex;
|
||||
}
|
||||
|
||||
int SearchResultModel::resultsCount() const
|
||||
{
|
||||
return mSearchResults.count();
|
||||
}
|
||||
|
||||
PSearchResults SearchResultModel::currentResults()
|
||||
{
|
||||
return results(mCurrentIndex);
|
||||
}
|
||||
|
||||
void SearchResultModel::setCurrentIndex(int index)
|
||||
{
|
||||
if (index!=mCurrentIndex &&
|
||||
index>=0 && index<mSearchResults.size()) {
|
||||
mCurrentIndex = index;
|
||||
emit currentChanged(mCurrentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SearchResultModel::clear()
|
||||
{
|
||||
mCurrentIndex = -1;
|
||||
mSearchResults.clear();
|
||||
emit modelChanged();
|
||||
}
|
||||
|
||||
SearchResultTreeModel::SearchResultTreeModel(SearchResultModel *model, QObject *parent):
|
||||
QAbstractItemModel(parent),
|
||||
mSearchResultModel(model)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SearchResultListModel::SearchResultListModel(SearchResultModel *model, QObject *parent):
|
||||
QAbstractListModel(parent),
|
||||
mSearchResultModel(model)
|
||||
{
|
||||
connect(mSearchResultModel, &SearchResultModel::currentChanged,
|
||||
this, &SearchResultListModel::onResultModelChanged);
|
||||
connect(mSearchResultModel, &SearchResultModel::modelChanged,
|
||||
this, &SearchResultListModel::onResultModelChanged);
|
||||
}
|
||||
|
||||
int SearchResultListModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return mSearchResultModel->resultsCount();
|
||||
}
|
||||
|
||||
QVariant SearchResultListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if (role == Qt::DisplayRole) {
|
||||
PSearchResults results = mSearchResultModel->results(index.row());
|
||||
if (!results)
|
||||
return QVariant();
|
||||
switch (results->scope) {
|
||||
case SearchFileScope::currentFile:
|
||||
return tr("Current File") + QString(" \"%1\"").arg(results->keyword);
|
||||
case SearchFileScope::wholeProject:
|
||||
return tr("Files In Project") + QString(" \"%1\"").arg(results->keyword);
|
||||
case SearchFileScope::openedFiles:
|
||||
return tr("Open Files") + QString(" \"%1\"").arg(results->keyword);
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void SearchResultListModel::onResultModelChanged()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef SEARCHRESULTVIEW_H
|
||||
#define SEARCHRESULTVIEW_H
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QMap>
|
||||
#include "../qsynedit/SearchBase.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define MAX_SEARCH_RESULTS 20
|
||||
|
||||
struct SearchResult {
|
||||
QString filename;
|
||||
int line;
|
||||
int start;
|
||||
int len;
|
||||
};
|
||||
|
||||
using PSearchResult = std::shared_ptr<SearchResult>;
|
||||
using SearchResultList = QList<PSearchResult>;
|
||||
using PSearchResultList = std::shared_ptr<SearchResultList>;
|
||||
|
||||
struct SearchResults{
|
||||
SynSearchOptions options;
|
||||
QString keyword;
|
||||
SearchFileScope scope;
|
||||
QMap<QString, PSearchResultList> results;
|
||||
};
|
||||
|
||||
using PSearchResults = std::shared_ptr<SearchResults>;
|
||||
|
||||
class SearchResultModel : QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchResultModel(QObject* parent=nullptr);
|
||||
PSearchResults addSearchResults(const QString& keyword,SynSearchOptions options,
|
||||
SearchFileScope scope);
|
||||
PSearchResults results(int index);
|
||||
int currentIndex() const;
|
||||
int resultsCount() const;
|
||||
PSearchResults currentResults();
|
||||
void setCurrentIndex(int index);
|
||||
void clear();
|
||||
signals:
|
||||
void modelChanged();
|
||||
void currentChanged(int index);
|
||||
private:
|
||||
QList<PSearchResults> mSearchResults;
|
||||
int mCurrentIndex;
|
||||
|
||||
};
|
||||
|
||||
class SearchResultListModel: public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
explicit SearchResultListModel(SearchResultModel* model,QObject* parent=nullptr);
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
public slots:
|
||||
void onResultModelChanged();
|
||||
private:
|
||||
SearchResultModel *mSearchResultModel;
|
||||
};
|
||||
|
||||
class SearchResultTreeModel : public QAbstractItemModel {
|
||||
Q_OBJECT
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
explicit SearchResultTreeModel(SearchResultModel* model,QObject* parent=nullptr);
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &child) const override;
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
private:
|
||||
SearchResultModel *mSearchResultModel;
|
||||
};
|
||||
|
||||
class SearchResultView : public QTreeView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SearchResultView(QWidget* parent=nullptr);
|
||||
};
|
||||
|
||||
#endif // SEARCHRESULTVIEW_H
|
Loading…
Reference in New Issue