work save

This commit is contained in:
royqh1979@gmail.com 2021-08-05 12:31:53 +08:00
parent 579b36ff49
commit ecc4934fd3
8 changed files with 330 additions and 202 deletions

View File

@ -107,6 +107,13 @@ MainWindow::MainWindow(QWidget *parent)
connect(ui->debugConsole,&QConsole::commandInput,this,&MainWindow::onDebugCommandInput); connect(ui->debugConsole,&QConsole::commandInput,this,&MainWindow::onDebugCommandInput);
connect(ui->cbEvaluate->lineEdit(), &QLineEdit::returnPressed, connect(ui->cbEvaluate->lineEdit(), &QLineEdit::returnPressed,
this, &MainWindow::onDebugEvaluateInput); this, &MainWindow::onDebugEvaluateInput);
mSearchResultTreeModel = std::make_shared<SearchResultTreeModel>(&mSearchResultModel);
mSearchResultListModel = std::make_shared<SearchResultListModel>(&mSearchResultModel);
mSearchViewDelegate = std::make_shared<SearchResultTreeViewDelegate>(mSearchResultTreeModel);
ui->cbSearchHistory->view()->setModel(mSearchResultListModel.get());
ui->searchView->setModel(mSearchResultTreeModel.get());
ui->searchView->setItemDelegate(mSearchViewDelegate.get());
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
@ -882,6 +889,11 @@ SearchDialog *MainWindow::searchDialog() const
return mSearchDialog; return mSearchDialog;
} }
SearchResultModel *MainWindow::searchResultModel()
{
return &mSearchResultModel;
}
EditorList *MainWindow::editorList() const EditorList *MainWindow::editorList() const
{ {
return mEditorList; return mEditorList;

View File

@ -3,6 +3,7 @@
#include <QMainWindow> #include <QMainWindow>
#include "common.h" #include "common.h"
#include "widgets/searchresultview.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }
@ -81,6 +82,8 @@ public:
SearchDialog *searchDialog() const; SearchDialog *searchDialog() const;
SearchResultModel* searchResultModel();
protected: protected:
void openFiles(const QStringList& files); void openFiles(const QStringList& files);
void openFile(const QString& filename); void openFile(const QString& filename);
@ -213,6 +216,11 @@ private:
SearchDialog *mSearchDialog; SearchDialog *mSearchDialog;
QList<QAction *> mRecentFileActions; QList<QAction *> mRecentFileActions;
SearchResultModel mSearchResultModel;
PSearchResultListModel mSearchResultListModel;
PSearchResultTreeModel mSearchResultTreeModel;
PSearchResultTreeViewDelegate mSearchViewDelegate;
bool mMessageControlChanged; bool mMessageControlChanged;
bool mTabMessagesTogglingState; bool mTabMessagesTogglingState;
bool mCheckSyntaxInBack; bool mCheckSyntaxInBack;

View File

@ -574,7 +574,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="comboBox"> <widget class="QComboBox" name="cbSearchHistory">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
@ -641,7 +641,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QComboBox" name="comboBox_2"> <widget class="QComboBox" name="cbReplaceInHistory">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>150</width> <width>150</width>
@ -680,7 +680,11 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QTreeView" name="searchView"/> <widget class="QTreeView" name="searchView">
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -1304,7 +1308,7 @@
<customwidget> <customwidget>
<class>IssuesTable</class> <class>IssuesTable</class>
<extends>QTableView</extends> <extends>QTableView</extends>
<header>widgets/issuestable.h</header> <header location="global">widgets/issuestable.h</header>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>QConsole</class> <class>QConsole</class>

View File

@ -214,6 +214,10 @@ public:
void setCaretXY(const BufferCoord& value); void setCaretXY(const BufferCoord& value);
void setCaretXYEx(bool CallEnsureCursorPos, BufferCoord value); void setCaretXYEx(bool CallEnsureCursorPos, BufferCoord value);
void setCaretXYCentered(bool ForceToMiddle, const BufferCoord& value); void setCaretXYCentered(bool ForceToMiddle, const BufferCoord& value);
void setCaretAndSelection(const BufferCoord& ptCaret,
const BufferCoord& ptBefore,
const BufferCoord& ptAfter);
void uncollapseAroundLine(int line); void uncollapseAroundLine(int line);
PSynEditFoldRange foldHidesLine(int line); PSynEditFoldRange foldHidesLine(int line);
void setSelText(const QString& Value); void setSelText(const QString& Value);
@ -451,9 +455,7 @@ private:
void DeleteFromTo(const BufferCoord& start, const BufferCoord& end); void DeleteFromTo(const BufferCoord& start, const BufferCoord& end);
void SetSelWord(); void SetSelWord();
void SetWordBlock(BufferCoord Value); void SetWordBlock(BufferCoord Value);
void setCaretAndSelection(const BufferCoord& ptCaret,
const BufferCoord& ptBefore,
const BufferCoord& ptAfter);
void processGutterClick(QMouseEvent* event); void processGutterClick(QMouseEvent* event);

View File

@ -7,6 +7,7 @@
#include "../qsynedit/Search.h" #include "../qsynedit/Search.h"
#include "../qsynedit/SearchRegex.h" #include "../qsynedit/SearchRegex.h"
#include <QMessageBox> #include <QMessageBox>
#include <QDebug>
SearchDialog::SearchDialog(QWidget *parent) : SearchDialog::SearchDialog(QWidget *parent) :
@ -122,7 +123,7 @@ void SearchDialog::on_btnCancel_clicked()
void SearchDialog::on_btnExecute_clicked() void SearchDialog::on_btnExecute_clicked()
{ {
int findcount = 0; int findCount = 0;
SearchAction actionType; SearchAction actionType;
switch (mTabBar->currentIndex()) { switch (mTabBar->currentIndex()) {
@ -187,13 +188,13 @@ void SearchDialog::on_btnExecute_clicked()
if (actionType == SearchAction::Find) { if (actionType == SearchAction::Find) {
Editor *e = pMainWindow->editorList()->getEditor(); Editor *e = pMainWindow->editorList()->getEditor();
if (e!=nullptr) { if (e!=nullptr) {
findcount+=execute(e,ui->cbFind->currentText(),""); findCount+=execute(e,ui->cbFind->currentText(),"");
} }
} else { } else if (actionType == SearchAction::Replace) {
Editor *e = pMainWindow->editorList()->getEditor(); Editor *e = pMainWindow->editorList()->getEditor();
if (e!=nullptr) { if (e!=nullptr) {
bool doPrompt = ui->chkPrompt->isChecked(); bool doPrompt = ui->chkPrompt->isChecked();
findcount+=execute(e,ui->cbFind->currentText(),ui->cbReplace->currentText(), findCount+=execute(e,ui->cbFind->currentText(),ui->cbReplace->currentText(),
[&doPrompt](const QString& sSearch, [&doPrompt](const QString& sSearch,
const QString& sReplace, int Line, int ch, int wordLen){ const QString& sReplace, int Line, int ch, int wordLen){
if (doPrompt) { if (doPrompt) {
@ -219,165 +220,67 @@ void SearchDialog::on_btnExecute_clicked()
}); });
} }
} else if (actionType == SearchAction::FindFiles) {
int fileSearched = 0;
int fileHitted = 0;
QString keyword = ui->cbFind->currentText();
if (ui->rbOpenFiles->isChecked()) {
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
keyword,
mSearchOptions,
SearchFileScope::openedFiles
);
// loop through editors, add results to message control
for (int i=0;i<pMainWindow->editorList()->pageCount();i++) {
Editor * e=pMainWindow->editorList()->operator[](i);
if (e!=nullptr) {
fileSearched++;
PSearchResultTreeItem parentItem = batchFindInEditor(e,
keyword);
int t = parentItem->results.size();
findCount+=t;
if (t>0) {
fileHitted++;
results->results.append(parentItem);
}
}
}
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
} else if (ui->rbCurrentFile->isChecked()) {
PSearchResults results = pMainWindow->searchResultModel()->addSearchResults(
keyword,
mSearchOptions,
SearchFileScope::openedFiles
);
Editor * e= pMainWindow->editorList()->getEditor();
if (e!=nullptr) {
fileSearched++;
PSearchResultTreeItem parentItem = batchFindInEditor(e,
keyword);
int t = parentItem->results.size();
findCount+=t;
if (t>0) {
fileHitted++;
results->results.append(parentItem);
}
}
pMainWindow->searchResultModel()->notifySearchResultsUpdated();
} else if (ui->rbProject->isChecked()) {
// end else if rbProjectFiles.Checked then begin
// for I := 0 to MainForm.Project.Units.Count - 1 do begin
// e := MainForm.Project.Units[i].Editor;
// fCurFile := MainForm.Project.Units[i].FileName;
// // file is already open, use memory
// if Assigned(e) then begin begin
// inc(fileSearched);
// t:=Execute(e.Text, actiontype);
// Inc(findcount, t);
// if t>0 then
// inc(filehitted);
// end;
}
} }
// // Replace first, find to next
//end else if actiontype = faReplace then begin
// e := MainForm.EditorList.GetEditor;
// if Assigned(e) then begin
// Inc(findcount, Execute(e.Text, faReplace));
// if findcount > 0 then begin
// Exclude(fSearchOptions, ssoReplace);
// Inc(findcount, Execute(e.Text, faFind));
// end;
// end;
// // Or find everything
//end else if actiontype = faFindFiles then begin
// fileSearched:=0;
// fileHitted:=0;
// MainForm.FindOutput.BeginFind(cboFindText.Text);
// try
// // loop through pagecontrol
// if rbOpenFiles.Checked then begin
// // loop through editors, add results to message control
// for I := 0 to MainForm.EditorList.PageCount - 1 do begin
// e := MainForm.EditorList[i];
// if Assigned(e) then begin
// inc(fileSearched);
// fCurFile := e.FileName;
// t:=Execute(e.Text, actiontype);
// Inc(findcount, t);
// if t>0 then
// inc(filehitted);
// end;
// end;
// // loop through project
// end else if rbProjectFiles.Checked then begin
// for I := 0 to MainForm.Project.Units.Count - 1 do begin
// e := MainForm.Project.Units[i].Editor;
// fCurFile := MainForm.Project.Units[i].FileName;
// // file is already open, use memory
// if Assigned(e) then begin begin
// inc(fileSearched);
// t:=Execute(e.Text, actiontype);
// Inc(findcount, t);
// if t>0 then
// inc(filehitted);
// end;
// // not open? load from disk
// end else if FileExists(fCurFile) then begin
// // Only finding...
// fTempSynEdit.Lines.LoadFromFile(fCurFile);
// inc(fileSearched);
// t:=Execute(fTempSynEdit, actiontype);
// Inc(findcount, t);
// if t>0 then
// inc(filehitted);
// end;
// end;
// // Don't loop, only pass single file
// end else if rbCurFile.Checked then begin
// e := MainForm.EditorList.GetEditor;
// if Assigned(e) then begin
// fCurFile := e.FileName;
// inc(fileSearched);
// t:=Execute(e.Text, actiontype);
// Inc(findcount, t);
// if t>0 then
// inc(filehitted);
// end;
// end;
// finally
// MainForm.FindOutput.EndFind(cboFindText.Text,findCount,
// filehitted,filesearched);
// end;
//end else if actiontype = faReplaceFiles then begin
// // loop through pagecontrol
// if rbOpenFiles.Checked then begin
// // loop through editors, add results to message control
// for I := 0 to MainForm.EditorList.PageCount - 1 do begin
// e := MainForm.EditorList[i];
// if Assigned(e) then begin
// fCurFile := e.FileName;
// if (ssoPrompt in fSearchOptions) then
// e.Activate;
// Inc(findcount, Execute(e.Text, actiontype));
// end;
// end;
// // loop through project
// end else if rbProjectFiles.Checked then begin
// for I := 0 to MainForm.Project.Units.Count - 1 do begin
// e := MainForm.Project.Units[i].Editor;
// fCurFile := MainForm.Project.Units[i].FileName;
// // file is already open, use memory
// if Assigned(e) then begin
// if (ssoPrompt in fSearchOptions) then
// e.Activate;
// Inc(findcount, Execute(e.Text, actiontype));
// // not open? load from disk
// end else if FileExists(fCurFile) then begin
// // we have to open an editor...
// if ssoPrompt in fSearchOptions then begin
// e := MainForm.EditorList.GetEditorFromFileName(fCurFile);
// if Assigned(e) then begin
// e.Activate;
// Inc(findcount, Execute(e.Text, actiontype));
// // Save and close
// e.Save;
// MainForm.Project.CloseUnit(MainForm.Project.Units.Indexof(e));
// end;
// end else begin
// // Stealth replace
// fTempSynEdit.Lines.LoadFromFile(fCurFile);
// Inc(findcount, Execute(fTempSynEdit, actiontype));
// fTempSynEdit.Lines.SaveToFile(fCurFile);
// end;
// end;
// end;
// // Don't loop, only pass single file
// end else if rbCurFile.Checked then begin
// e := MainForm.EditorList.GetEditor;
// if Assigned(e) then begin
// fCurFile := e.FileName;
// Inc(findcount, Execute(e.Text, actiontype));
// end;
// end;
//end;
//if actiontype = faFindFiles then begin
// MainForm.MessageControl.ActivePageIndex := 4; // Find Tab
// if findcount > 0 then
// MainForm.FindSheet.Caption := Lang[ID_SHEET_FIND];
// MainForm.OpenCloseMessageSheet(TRUE);
// self.Close;
//end else if findcount = 0 then begin
// MessageBox(
// Self.Handle,
// PAnsiChar(Format(Lang[ID_MSG_TEXTNOTFOUND], [cboFindText.Text])),
// PAnsiChar(Lang[ID_INFO]),
// MB_ICONINFORMATION or MB_TOPMOST);
// cboFindText.SetFocus;
//end;
//if actiontype = faFind then begin
// self.Close;
//end;
} }
int SearchDialog::execute(Editor *editor, const QString &sSearch, const QString &sReplace, SynSearchMathedProc matchCallback) int SearchDialog::execute(Editor *editor, const QString &sSearch, const QString &sReplace, SynSearchMathedProc matchCallback)
@ -403,30 +306,44 @@ int SearchDialog::execute(Editor *editor, const QString &sSearch, const QString
return editor->searchReplace(sSearch, sReplace, mSearchOptions, return editor->searchReplace(sSearch, sReplace, mSearchOptions,
mSearchEngine, matchCallback); mSearchEngine, matchCallback);
}
std::shared_ptr<SearchResultTreeItem> SearchDialog::batchFindInEditor(Editor *e, const QString &keyword)
{
//backup
BufferCoord caretBackup = e->caretXY();
BufferCoord blockBeginBackup = e->blockBegin();
BufferCoord blockEndBackup = e->blockEnd();
int toplineBackup = e->topLine();
int leftCharBackup = e->leftChar();
// // When using find in files, report each find using OnReplaceText PSearchResultTreeItem parentItem = std::make_shared<SearchResultTreeItem>();
// if action = faFindFiles then parentItem->filename = e->filename();
// editor.OnReplaceText := FindAllAction; parentItem->parent = nullptr;
execute(e,keyword,"",
[e,&parentItem](const QString&,
const QString&, int Line, int ch, int wordLen){
PSearchResultTreeItem item = std::make_shared<SearchResultTreeItem>();
item->filename = e->filename();
item->line = Line;
item->start = ch;
item->len = wordLen;
item->parent = parentItem.get();
item->text = e->lines()->getString(Line-1);
parentItem->results.append(item);
return SynSearchAction::Skip;
});
// // Swap search engire for ours // restore
// if (ssoRegExp in fSearchOptions) then e->setCaretXY(caretBackup);
// editor.SearchEngine := fRegExpSearchEngine e->setTopLine(toplineBackup);
// else e->setLeftChar(leftCharBackup);
// editor.SearchEngine := fSearchEngine; e->setCaretAndSelection(
// result := editor.SearchReplace(cboFindText.Text, cboReplaceText.Text, fSearchOptions); caretBackup,
blockBeginBackup,
// // Don't touch editors which we are only scanning blockEndBackup
// if action in [faFindFiles] then begin );
// // Put backup back into place return parentItem;
// editor.CaretXY := caretbackup;
// editor.BlockBegin := blockbeginbackup;
// editor.BlockEnd := blockendbackup;
// editor.TopLine := toplinebackup;
// end;
// editor.OnReplaceText := onreplacebackup;
// editor.SearchEngine := enginebackup;
} }
QTabBar *SearchDialog::tabBar() const QTabBar *SearchDialog::tabBar() const

View File

@ -8,6 +8,7 @@ namespace Ui {
class SearchDialog; class SearchDialog;
} }
struct SearchResultTreeItem;
class QTabBar; class QTabBar;
class Editor; class Editor;
class SearchDialog : public QDialog class SearchDialog : public QDialog
@ -43,6 +44,7 @@ private slots:
private: private:
int execute(Editor* editor, const QString& sSearch, int execute(Editor* editor, const QString& sSearch,
const QString& sReplace, SynSearchMathedProc matchCallback = nullptr); const QString& sReplace, SynSearchMathedProc matchCallback = nullptr);
std::shared_ptr<SearchResultTreeItem> batchFindInEditor(Editor* editor,const QString& keyword);
private: private:
Ui::SearchDialog *ui; Ui::SearchDialog *ui;
QTabBar *mTabBar; QTabBar *mTabBar;

View File

@ -1,4 +1,8 @@
#include "searchresultview.h" #include "searchresultview.h"
#include <QApplication>
#include <QPainter>
#include <QStyledItemDelegate>
#include "mainwindow.h"
PSearchResults SearchResultModel::addSearchResults(const QString &keyword, SynSearchOptions options, SearchFileScope scope) PSearchResults SearchResultModel::addSearchResults(const QString &keyword, SynSearchOptions options, SearchFileScope scope)
{ {
@ -10,7 +14,7 @@ PSearchResults SearchResultModel::addSearchResults(const QString &keyword, SynSe
break; break;
} }
} }
if (index>0) { if (index>=0) {
mSearchResults.removeAt(index); mSearchResults.removeAt(index);
} }
if (mSearchResults.size()>=MAX_SEARCH_RESULTS) { if (mSearchResults.size()>=MAX_SEARCH_RESULTS) {
@ -21,7 +25,7 @@ PSearchResults SearchResultModel::addSearchResults(const QString &keyword, SynSe
results->options = options; results->options = options;
results->scope = scope; results->scope = scope;
mSearchResults.push_front(results); mSearchResults.push_front(results);
emit modelChanged(); mCurrentIndex = 0;
return results; return results;
} }
@ -33,6 +37,11 @@ PSearchResults SearchResultModel::results(int index)
return mSearchResults[index]; return mSearchResults[index];
} }
void SearchResultModel::notifySearchResultsUpdated()
{
emit modelChanged();
}
SearchResultModel::SearchResultModel(QObject* parent): SearchResultModel::SearchResultModel(QObject* parent):
QObject(parent), QObject(parent),
mCurrentIndex(-1) mCurrentIndex(-1)
@ -75,7 +84,111 @@ SearchResultTreeModel::SearchResultTreeModel(SearchResultModel *model, QObject *
QAbstractItemModel(parent), QAbstractItemModel(parent),
mSearchResultModel(model) mSearchResultModel(model)
{ {
connect(mSearchResultModel,&SearchResultModel::currentChanged,
this,&SearchResultTreeModel::onResultModelChanged);
connect(mSearchResultModel,&SearchResultModel::modelChanged,
this,&SearchResultTreeModel::onResultModelChanged);
}
QModelIndex SearchResultTreeModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row,column,parent))
return QModelIndex();
PSearchResults results = mSearchResultModel->currentResults();
if (!results)
return QModelIndex();
SearchResultTreeItem *parentItem=nullptr;
PSearchResultTreeItem childItem;
if (!parent.isValid()) {
parentItem = nullptr;
childItem = results->results[row];
} else {
parentItem = static_cast<SearchResultTreeItem *>(parent.internalPointer());
childItem = parentItem->results[row];
}
if (childItem)
return createIndex(row,column,childItem.get());
return QModelIndex();
}
QModelIndex SearchResultTreeModel::parent(const QModelIndex &child) const
{
if (!child.isValid())
return QModelIndex();
SearchResultTreeItem* item = static_cast<SearchResultTreeItem *>(child.internalPointer());
if (!item) {
return QModelIndex();
} else {
if (item->parent==nullptr)
return QModelIndex();
SearchResultTreeItem* parent = item->parent;
int row = -1;
for (int i=0;i<parent->results.count();i++) {
if (parent->results[i].get()==item) {
row = i;
break;
}
}
return createIndex(row,0,parent);
}
}
int SearchResultTreeModel::rowCount(const QModelIndex &parent) const
{
if (!parent.isValid()){ //root
PSearchResults searchResults = mSearchResultModel->currentResults();
if (!searchResults)
return 0;
return searchResults->results.count();
}
SearchResultTreeItem* item = static_cast<SearchResultTreeItem *>(parent.internalPointer()); if (!item)
return 0;
return item->results.count();
}
int SearchResultTreeModel::columnCount(const QModelIndex &parent) const
{
return 1;
}
QVariant SearchResultTreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()){
return QVariant();
}
SearchResultTreeItem *item = static_cast<SearchResultTreeItem *>(index.internalPointer());
if (!item)
return QVariant();
if (role == Qt::DisplayRole) {
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 item->filename;
} else {
return QString("%1 %2: %3").arg(tr("Line")).arg(item->line)
.arg(item->text);
}
}
return QVariant();
}
SearchResultModel *SearchResultTreeModel::searchResultModel() const
{
return mSearchResultModel;
}
void SearchResultTreeModel::onResultModelChanged()
{
beginResetModel();
endResetModel();
} }
SearchResultListModel::SearchResultListModel(SearchResultModel *model, QObject *parent): SearchResultListModel::SearchResultListModel(SearchResultModel *model, QObject *parent):
@ -118,3 +231,53 @@ void SearchResultListModel::onResultModelChanged()
beginResetModel(); beginResetModel();
endResetModel(); endResetModel();
} }
/**
*
* see https://stackoverflow.com/questions/1956542/how-to-make-item-view-render-rich-html-text-in-qt/66412883#66412883
*/
SearchResultTreeViewDelegate::SearchResultTreeViewDelegate(PSearchResultTreeModel model, QObject *parent):
QStyledItemDelegate(parent),
mModel(model)
{
}
void SearchResultTreeViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optIn, const QModelIndex &index) const
{
QStyleOptionViewItem option = optIn;
initStyleOption(&option,index);
PSearchResults results = mModel->searchResultModel()->currentResults();
if (!results || !index.isValid() ) {
// This is nothing this function is supposed to handle
return;
}
QStyle *style = option.widget ? option.widget->style() : QApplication::style();
// Painting item without text (this takes care of painting e.g. the highlighted for selected
// or hovered over items in an ItemView)
option.text = QString();
style->drawControl(QStyle::CE_ItemViewItem, &option, painter, option.widget);
SearchResultTreeItem* item = static_cast<SearchResultTreeItem *>(index.internalPointer());
QString fullText;
if (item->parent==nullptr) { //is filename
fullText = item->filename;
} else {
fullText = QString("%1 %2: %3").arg(tr("Line")).arg(item->line)
.arg(item->text);
}
// Figure out where to render the text in order to follow the requested alignment
option.text = fullText;
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &option);
QFontMetrics metrics = option.fontMetrics;
int x=textRect.left();
int y=textRect.top() + metrics.ascent();
//painter->setClipRect(textRect);
painter->drawText(x,y,fullText);
}

View File

@ -3,38 +3,45 @@
#include <QTreeView> #include <QTreeView>
#include <QMap> #include <QMap>
#include <QStyledItemDelegate>
#include "../qsynedit/SearchBase.h" #include "../qsynedit/SearchBase.h"
#include "utils.h" #include "utils.h"
#define MAX_SEARCH_RESULTS 20 #define MAX_SEARCH_RESULTS 20
struct SearchResultTreeItem;
using PSearchResultTreeItem = std::shared_ptr<SearchResultTreeItem>;
using SearchResultTreeItemList = QList<PSearchResultTreeItem>;
using PSearchResultTreeItemList = std::shared_ptr<SearchResultTreeItemList>;
struct SearchResult { struct SearchResultTreeItem {
QString filename; QString filename;
int line; int line;
int start; int start;
int len; int len;
QString text;
SearchResultTreeItem* parent;
SearchResultTreeItemList results;
}; };
using PSearchResult = std::shared_ptr<SearchResult>;
using SearchResultList = QList<PSearchResult>;
using PSearchResultList = std::shared_ptr<SearchResultList>;
struct SearchResults{ struct SearchResults{
SynSearchOptions options; SynSearchOptions options;
QString keyword; QString keyword;
SearchFileScope scope; SearchFileScope scope;
QMap<QString, PSearchResultList> results; QList<PSearchResultTreeItem> results;
}; };
using PSearchResults = std::shared_ptr<SearchResults>; using PSearchResults = std::shared_ptr<SearchResults>;
class SearchResultModel : QObject { class SearchResultModel : public QObject {
Q_OBJECT Q_OBJECT
public: public:
explicit SearchResultModel(QObject* parent=nullptr); explicit SearchResultModel(QObject* parent=nullptr);
PSearchResults addSearchResults(const QString& keyword,SynSearchOptions options, PSearchResults addSearchResults(const QString& keyword,SynSearchOptions options,
SearchFileScope scope); SearchFileScope scope);
PSearchResults results(int index); PSearchResults results(int index);
void notifySearchResultsUpdated();
int currentIndex() const; int currentIndex() const;
int resultsCount() const; int resultsCount() const;
PSearchResults currentResults(); PSearchResults currentResults();
@ -62,6 +69,8 @@ private:
SearchResultModel *mSearchResultModel; SearchResultModel *mSearchResultModel;
}; };
using PSearchResultListModel = std::shared_ptr<SearchResultListModel>;
class SearchResultTreeModel : public QAbstractItemModel { class SearchResultTreeModel : public QAbstractItemModel {
Q_OBJECT Q_OBJECT
// QAbstractItemModel interface // QAbstractItemModel interface
@ -72,15 +81,26 @@ public:
int rowCount(const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent) const override;
int columnCount(const QModelIndex &parent) const override; int columnCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override; QVariant data(const QModelIndex &index, int role) const override;
SearchResultModel *searchResultModel() const;
public slots:
void onResultModelChanged();
private: private:
SearchResultModel *mSearchResultModel; SearchResultModel *mSearchResultModel;
}; };
class SearchResultView : public QTreeView using PSearchResultTreeModel = std::shared_ptr<SearchResultTreeModel>;
{
Q_OBJECT class SearchResultTreeViewDelegate: public QStyledItemDelegate{
Q_OBJECT
// QAbstractItemDelegate interface
public: public:
explicit SearchResultView(QWidget* parent=nullptr); explicit SearchResultTreeViewDelegate(PSearchResultTreeModel model,
QObject* parent=nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
private:
PSearchResultTreeModel mModel;
}; };
using PSearchResultTreeViewDelegate = std::shared_ptr<SearchResultTreeViewDelegate>;
#endif // SEARCHRESULTVIEW_H #endif // SEARCHRESULTVIEW_H