- enhancement: replace in files
- enhancement: refactor in project (using search symbol occurence and replace in files) - fix: search in files
This commit is contained in:
parent
35b7bdb18c
commit
75a6b75ebb
3
NEWS.md
3
NEWS.md
|
@ -10,6 +10,9 @@ Version 0.6.0
|
||||||
- enhancement: don't add encoding options when using clang to compile (clang only support utf-8)
|
- enhancement: don't add encoding options when using clang to compile (clang only support utf-8)
|
||||||
- enhancement: find occurence in project
|
- enhancement: find occurence in project
|
||||||
- implement: refactor in file
|
- implement: refactor in file
|
||||||
|
- enhancement: replace in files
|
||||||
|
- enhancement: refactor in project (using search symbol occurence and replace in files)
|
||||||
|
- fix: search in files
|
||||||
|
|
||||||
Version 0.5.0
|
Version 0.5.0
|
||||||
- enhancement: support C++ using type alias;
|
- enhancement: support C++ using type alias;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1272,9 +1272,10 @@ void MainWindow::debug()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showSearchPanel()
|
void MainWindow::showSearchPanel(bool showReplace)
|
||||||
{
|
{
|
||||||
openCloseBottomPanel(true);
|
openCloseBottomPanel(true);
|
||||||
|
showSearchReplacePanel(showReplace);
|
||||||
ui->tabMessages->setCurrentWidget(ui->tabSearch);
|
ui->tabMessages->setCurrentWidget(ui->tabSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3539,8 +3540,7 @@ void MainWindow::on_actionFind_references_triggered()
|
||||||
if (editor && editor->pointToCharLine(mEditorContextMenuPos,pos)) {
|
if (editor && editor->pointToCharLine(mEditorContextMenuPos,pos)) {
|
||||||
CppRefacter refactor;
|
CppRefacter refactor;
|
||||||
refactor.findOccurence(editor,pos);
|
refactor.findOccurence(editor,pos);
|
||||||
ui->tabMessages->setCurrentWidget(ui->tabSearch);
|
showSearchPanel(true);
|
||||||
openCloseBottomPanel(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3973,6 +3973,37 @@ void MainWindow::on_actionRename_Symbol_triggered()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufferCoord oldCaretXY = editor->caretXY();
|
||||||
|
if (editor->inProject() && mProject) {
|
||||||
|
mProject->cppParser()->parseFileList();
|
||||||
|
BufferCoord pBeginPos,pEndPos;
|
||||||
|
QString phrase = getWordAtPosition(editor,oldCaretXY,pBeginPos,pEndPos,Editor::WordPurpose::wpInformation);
|
||||||
|
// Find it's definition
|
||||||
|
PStatement oldStatement = editor->parser()->findStatementOf(
|
||||||
|
editor->filename(),
|
||||||
|
phrase,
|
||||||
|
oldCaretXY.Line);
|
||||||
|
// definition of the symbol not found
|
||||||
|
if (!oldStatement)
|
||||||
|
return;
|
||||||
|
// found but not in this file
|
||||||
|
if (editor->filename() != oldStatement->fileName
|
||||||
|
|| editor->filename() != oldStatement->definitionFileName) {
|
||||||
|
// it's defined in system header, dont rename
|
||||||
|
if (mProject->cppParser()->isSystemHeaderFile(oldStatement->fileName)) {
|
||||||
|
QMessageBox::critical(editor,
|
||||||
|
tr("Rename Error"),
|
||||||
|
tr("Symbol '%1' is defined in system header.")
|
||||||
|
.arg(oldStatement->fullName));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CppRefacter refactor;
|
||||||
|
refactor.findOccurence(editor,oldCaretXY);
|
||||||
|
showSearchPanel(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
QString newWord = QInputDialog::getText(editor,
|
QString newWord = QInputDialog::getText(editor,
|
||||||
tr("Rename Symbol"),
|
tr("Rename Symbol"),
|
||||||
|
@ -3985,7 +4016,6 @@ void MainWindow::on_actionRename_Symbol_triggered()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PCppParser parser = editor->parser();
|
PCppParser parser = editor->parser();
|
||||||
BufferCoord oldCaretXY = editor->caretXY();
|
|
||||||
//here we must reparse the file in sync, or rename may fail
|
//here we must reparse the file in sync, or rename may fail
|
||||||
parser->parseFile(editor->filename(), editor->inProject(), false, false);
|
parser->parseFile(editor->filename(), editor->inProject(), false, false);
|
||||||
CppRefacter refactor;
|
CppRefacter refactor;
|
||||||
|
@ -3994,3 +4024,53 @@ void MainWindow::on_actionRename_Symbol_triggered()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::showSearchReplacePanel(bool show)
|
||||||
|
{
|
||||||
|
ui->replacePanel->setVisible(show);
|
||||||
|
ui->cbSearchHistory->setDisabled(show);
|
||||||
|
if (show && mSearchResultModel.currentResults()) {
|
||||||
|
ui->cbReplaceInHistory->setCurrentText(
|
||||||
|
mSearchResultModel.currentResults()->keyword);
|
||||||
|
}
|
||||||
|
mSearchResultTreeModel->setSelectable(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_btnReplace_clicked()
|
||||||
|
{
|
||||||
|
//select all items by default
|
||||||
|
PSearchResults results = mSearchResultModel.currentResults();
|
||||||
|
if (!results) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QString newWord = ui->cbReplaceInHistory->currentText();
|
||||||
|
foreach (const PSearchResultTreeItem& file, results->results) {
|
||||||
|
QStringList contents;
|
||||||
|
Editor* editor = mEditorList->getEditorByFilename(file->filename);
|
||||||
|
if (!editor) {
|
||||||
|
QMessageBox::critical(this,
|
||||||
|
tr("Replace Error"),
|
||||||
|
tr("Can't open file '%1' for replace!").arg(file->filename));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
contents = editor->lines()->contents();
|
||||||
|
for (int i=file->results.count()-1;i>=0;i--) {
|
||||||
|
const PSearchResultTreeItem& item = file->results[i];
|
||||||
|
QString line = contents[item->line-1];
|
||||||
|
if (line.mid(item->start-1,results->keyword.length())!=results->keyword) {
|
||||||
|
QMessageBox::critical(editor,
|
||||||
|
tr("Replace Error"),
|
||||||
|
tr("Contents has changed since last search!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
line.remove(item->start-1,results->keyword.length());
|
||||||
|
line.insert(item->start-1, newWord);
|
||||||
|
contents[item->line-1] = line;
|
||||||
|
}
|
||||||
|
editor->selectAll();
|
||||||
|
editor->setSelText(contents.join(editor->lineBreak()));
|
||||||
|
}
|
||||||
|
showSearchReplacePanel(false);
|
||||||
|
openCloseBottomPanel(false);
|
||||||
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public:
|
||||||
void runExecutable(const QString& exeName, const QString& filename=QString());
|
void runExecutable(const QString& exeName, const QString& filename=QString());
|
||||||
void runExecutable();
|
void runExecutable();
|
||||||
void debug();
|
void debug();
|
||||||
void showSearchPanel();
|
void showSearchPanel(bool showReplace = false);
|
||||||
|
|
||||||
void applySettings();
|
void applySettings();
|
||||||
void applyUISettings();
|
void applyUISettings();
|
||||||
|
@ -173,6 +173,8 @@ private:
|
||||||
QKeySequence shortcut=QKeySequence());
|
QKeySequence shortcut=QKeySequence());
|
||||||
void scanActiveProject(bool parse=false);
|
void scanActiveProject(bool parse=false);
|
||||||
void includeOrSkipDirs(const QStringList& dirs, bool skip);
|
void includeOrSkipDirs(const QStringList& dirs, bool skip);
|
||||||
|
void showSearchReplacePanel(bool show);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAutoSaveTimeout();
|
void onAutoSaveTimeout();
|
||||||
void onFileChanged(const QString& path);
|
void onFileChanged(const QString& path);
|
||||||
|
@ -373,6 +375,8 @@ private slots:
|
||||||
|
|
||||||
void on_actionRename_Symbol_triggered();
|
void on_actionRename_Symbol_triggered();
|
||||||
|
|
||||||
|
void on_btnReplace_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
EditorList *mEditorList;
|
EditorList *mEditorList;
|
||||||
|
|
|
@ -283,7 +283,7 @@
|
||||||
<enum>QTabWidget::South</enum>
|
<enum>QTabWidget::South</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>2</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tabIssues">
|
<widget class="QWidget" name="tabIssues">
|
||||||
<attribute name="icon">
|
<attribute name="icon">
|
||||||
|
|
|
@ -24,7 +24,7 @@ int SynSearch::resultCount()
|
||||||
return mResults.count();
|
return mResults.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SynSearch::findAll(const QString &keyword)
|
int SynSearch::findAll(const QString &text)
|
||||||
{
|
{
|
||||||
mResults.clear();
|
mResults.clear();
|
||||||
if (pattern().isEmpty())
|
if (pattern().isEmpty())
|
||||||
|
@ -33,18 +33,18 @@ int SynSearch::findAll(const QString &keyword)
|
||||||
int next=-1;
|
int next=-1;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (options().testFlag(ssoMatchCase)) {
|
if (options().testFlag(ssoMatchCase)) {
|
||||||
next = keyword.indexOf(pattern(),start,Qt::CaseSensitive);
|
next = text.indexOf(pattern(),start,Qt::CaseSensitive);
|
||||||
} else {
|
} else {
|
||||||
next = keyword.indexOf(pattern(),start,Qt::CaseInsensitive);
|
next = text.indexOf(pattern(),start,Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
if (next<0) {
|
if (next<0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
start = next + keyword.length();
|
start = next + pattern().length();
|
||||||
if (options().testFlag(ssoWholeWord)) {
|
if (options().testFlag(ssoWholeWord)) {
|
||||||
if (((next<=0) || isDelimitChar(keyword[next-1]))
|
if (((next<=0) || isDelimitChar(text[next-1]))
|
||||||
&&
|
&&
|
||||||
( (start>=keyword.length()) || isDelimitChar(keyword[start]) )
|
( (start>=text.length()) || isDelimitChar(text[start]) )
|
||||||
) {
|
) {
|
||||||
mResults.append(next);
|
mResults.append(next);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
int length(int aIndex) override;
|
int length(int aIndex) override;
|
||||||
int result(int aIndex) override;
|
int result(int aIndex) override;
|
||||||
int resultCount() override;
|
int resultCount() override;
|
||||||
int findAll(const QString &keyword) override;
|
int findAll(const QString &text) override;
|
||||||
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
||||||
private:
|
private:
|
||||||
bool isDelimitChar(QChar ch);
|
bool isDelimitChar(QChar ch);
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
virtual int length(int aIndex) = 0;
|
virtual int length(int aIndex) = 0;
|
||||||
virtual int result(int aIndex) = 0;
|
virtual int result(int aIndex) = 0;
|
||||||
virtual int resultCount() = 0;
|
virtual int resultCount() = 0;
|
||||||
virtual int findAll(const QString& keyword) = 0;
|
virtual int findAll(const QString& text) = 0;
|
||||||
virtual QString replace(const QString& aOccurrence, const QString& aReplacement) = 0;
|
virtual QString replace(const QString& aOccurrence, const QString& aReplacement) = 0;
|
||||||
SynSearchOptions options() const;
|
SynSearchOptions options() const;
|
||||||
virtual void setOptions(const SynSearchOptions &options);
|
virtual void setOptions(const SynSearchOptions &options);
|
||||||
|
|
|
@ -26,13 +26,13 @@ int SynSearchRegex::resultCount()
|
||||||
return mResults.size();
|
return mResults.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SynSearchRegex::findAll(const QString &keyword)
|
int SynSearchRegex::findAll(const QString &text)
|
||||||
{
|
{
|
||||||
if (pattern().isEmpty())
|
if (pattern().isEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
mResults.clear();
|
mResults.clear();
|
||||||
mLengths.clear();
|
mLengths.clear();
|
||||||
QRegularExpressionMatchIterator it = mRegex.globalMatch(keyword);
|
QRegularExpressionMatchIterator it = mRegex.globalMatch(text);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QRegularExpressionMatch match = it.next();
|
QRegularExpressionMatch match = it.next();
|
||||||
mLengths.append(match.capturedLength());
|
mLengths.append(match.capturedLength());
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
int length(int aIndex) override;
|
int length(int aIndex) override;
|
||||||
int result(int aIndex) override;
|
int result(int aIndex) override;
|
||||||
int resultCount() override;
|
int resultCount() override;
|
||||||
int findAll(const QString &keyword) override;
|
int findAll(const QString &text) override;
|
||||||
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
QString replace(const QString &aOccurrence, const QString &aReplacement) override;
|
||||||
void setPattern(const QString &value) override;
|
void setPattern(const QString &value) override;
|
||||||
void setOptions(const SynSearchOptions &options) override;
|
void setOptions(const SynSearchOptions &options) override;
|
||||||
|
|
|
@ -21,6 +21,7 @@ SearchDialog::SearchDialog(QWidget *parent) :
|
||||||
mTabBar->addTab(tr("Find"));
|
mTabBar->addTab(tr("Find"));
|
||||||
mTabBar->addTab(tr("Find in files"));
|
mTabBar->addTab(tr("Find in files"));
|
||||||
mTabBar->addTab(tr("Replace"));
|
mTabBar->addTab(tr("Replace"));
|
||||||
|
mTabBar->addTab(tr("Replace in files"));
|
||||||
mTabBar->setExpanding(false);
|
mTabBar->setExpanding(false);
|
||||||
ui->dialogLayout->insertWidget(0,mTabBar);
|
ui->dialogLayout->insertWidget(0,mTabBar);
|
||||||
connect(mTabBar,&QTabBar::currentChanged,this, &SearchDialog::onTabChanged);
|
connect(mTabBar,&QTabBar::currentChanged,this, &SearchDialog::onTabChanged);
|
||||||
|
@ -101,7 +102,7 @@ void SearchDialog::replace(const QString &sFind, const QString &sReplace)
|
||||||
void SearchDialog::onTabChanged()
|
void SearchDialog::onTabChanged()
|
||||||
{
|
{
|
||||||
bool isfind = (mTabBar->currentIndex() == 0);
|
bool isfind = (mTabBar->currentIndex() == 0);
|
||||||
bool isfindfiles = (mTabBar->currentIndex() == 1);
|
bool isfindfiles = (mTabBar->currentIndex() == 1 || mTabBar->currentIndex() == 3 );
|
||||||
bool isreplace = (mTabBar->currentIndex() == 2);
|
bool isreplace = (mTabBar->currentIndex() == 2);
|
||||||
|
|
||||||
ui->lblReplace->setVisible(isreplace);
|
ui->lblReplace->setVisible(isreplace);
|
||||||
|
@ -246,7 +247,7 @@ void SearchDialog::on_btnExecute_clicked()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (actionType == SearchAction::FindFiles) {
|
} else if (actionType == SearchAction::FindFiles || actionType == SearchAction::ReplaceFiles) {
|
||||||
int fileSearched = 0;
|
int fileSearched = 0;
|
||||||
int fileHitted = 0;
|
int fileHitted = 0;
|
||||||
QString keyword = ui->cbFind->currentText();
|
QString keyword = ui->cbFind->currentText();
|
||||||
|
@ -339,7 +340,7 @@ void SearchDialog::on_btnExecute_clicked()
|
||||||
// end;
|
// end;
|
||||||
}
|
}
|
||||||
if (findCount>0)
|
if (findCount>0)
|
||||||
pMainWindow->showSearchPanel();
|
pMainWindow->showSearchPanel(actionType == SearchAction::ReplaceFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,7 +119,8 @@ void SearchResultModel::removeSearchResults(int index)
|
||||||
|
|
||||||
SearchResultTreeModel::SearchResultTreeModel(SearchResultModel *model, QObject *parent):
|
SearchResultTreeModel::SearchResultTreeModel(SearchResultModel *model, QObject *parent):
|
||||||
QAbstractItemModel(parent),
|
QAbstractItemModel(parent),
|
||||||
mSearchResultModel(model)
|
mSearchResultModel(model),
|
||||||
|
mSelectable(false)
|
||||||
{
|
{
|
||||||
connect(mSearchResultModel,&SearchResultModel::currentChanged,
|
connect(mSearchResultModel,&SearchResultModel::currentChanged,
|
||||||
this,&SearchResultTreeModel::onResultModelChanged);
|
this,&SearchResultTreeModel::onResultModelChanged);
|
||||||
|
@ -213,6 +214,21 @@ QVariant SearchResultTreeModel::data(const QModelIndex &index, int role) const
|
||||||
.arg(item->text);
|
.arg(item->text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (role == Qt::CheckStateRole && mSelectable) {
|
||||||
|
|
||||||
|
PSearchResults results = mSearchResultModel->currentResults();
|
||||||
|
|
||||||
|
if (!results || !index.isValid() ) {
|
||||||
|
// This is nothing this function is supposed to handle
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->parent==nullptr) { //is filename
|
||||||
|
return QVariant();
|
||||||
|
} else {
|
||||||
|
return (item->selected)?Qt::Checked:Qt::Unchecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -256,6 +272,69 @@ void SearchResultTreeModel::onResultModelChanged()
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags SearchResultTreeModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
Qt::ItemFlags flags=Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
|
if (mSelectable) {
|
||||||
|
flags.setFlag(Qt::ItemIsUserCheckable);
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SearchResultTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (!index.isValid()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
SearchResultTreeItem *item = static_cast<SearchResultTreeItem *>(index.internalPointer());
|
||||||
|
if (!item)
|
||||||
|
return false;
|
||||||
|
if (role == Qt::CheckStateRole && mSelectable) {
|
||||||
|
|
||||||
|
PSearchResults results = mSearchResultModel->currentResults();
|
||||||
|
|
||||||
|
if (!results || !index.isValid() ) {
|
||||||
|
// This is nothing this function is supposed to handle
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item->parent==nullptr) { //is filename
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
item->selected = value.toBool();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SearchResultTreeModel::selectable() const
|
||||||
|
{
|
||||||
|
return mSelectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SearchResultTreeModel::setSelectable(bool newSelectable)
|
||||||
|
{
|
||||||
|
if (newSelectable!=mSelectable) {
|
||||||
|
beginResetModel();
|
||||||
|
mSelectable = newSelectable;
|
||||||
|
if (mSelectable) {
|
||||||
|
//select all items by default
|
||||||
|
PSearchResults results = mSearchResultModel->currentResults();
|
||||||
|
if (results) {
|
||||||
|
foreach (const PSearchResultTreeItem& file, results->results) {
|
||||||
|
file->selected = false;
|
||||||
|
foreach (const PSearchResultTreeItem& item, file->results) {
|
||||||
|
item->selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SearchResultListModel::SearchResultListModel(SearchResultModel *model, QObject *parent):
|
SearchResultListModel::SearchResultListModel(SearchResultModel *model, QObject *parent):
|
||||||
QAbstractListModel(parent),
|
QAbstractListModel(parent),
|
||||||
mSearchResultModel(model)
|
mSearchResultModel(model)
|
||||||
|
|
|
@ -26,6 +26,7 @@ struct SearchResultTreeItem {
|
||||||
QString text;
|
QString text;
|
||||||
SearchResultTreeItem* parent;
|
SearchResultTreeItem* parent;
|
||||||
SearchResultTreeItemList results;
|
SearchResultTreeItemList results;
|
||||||
|
bool selected;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SearchResults{
|
struct SearchResults{
|
||||||
|
@ -98,10 +99,22 @@ public:
|
||||||
QString& filename,
|
QString& filename,
|
||||||
int& line,
|
int& line,
|
||||||
int& startChar);
|
int& startChar);
|
||||||
|
bool selectable() const;
|
||||||
|
void setSelectable(bool newSelectable);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onResultModelChanged();
|
void onResultModelChanged();
|
||||||
private:
|
private:
|
||||||
SearchResultModel *mSearchResultModel;
|
SearchResultModel *mSearchResultModel;
|
||||||
|
bool mSelectable;
|
||||||
|
|
||||||
|
// QAbstractItemModel interface
|
||||||
|
public:
|
||||||
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
|
||||||
|
// QAbstractItemModel interface
|
||||||
|
public:
|
||||||
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
using PSearchResultTreeModel = std::shared_ptr<SearchResultTreeModel>;
|
using PSearchResultTreeModel = std::shared_ptr<SearchResultTreeModel>;
|
||||||
|
|
Loading…
Reference in New Issue