- redesign the project parser, more efficient and correct
- enhancement: todo parser for project
This commit is contained in:
parent
f0bdfed9b4
commit
e8300abd65
5
NEWS.md
5
NEWS.md
|
@ -1,3 +1,8 @@
|
|||
Red Panda C++ Version 2.0
|
||||
|
||||
- redesign the project parser, more efficient and correct
|
||||
- enhancement: todo parser for project
|
||||
|
||||
Red Panda C++ Version 1.5
|
||||
|
||||
- fix: project files that lies in project include folder is wrongly openned in Read-only mode
|
||||
|
|
|
@ -1290,6 +1290,8 @@ void Editor::showEvent(QShowEvent */*event*/)
|
|||
}
|
||||
pMainWindow->debugger()->setIsForProject(inProject());
|
||||
pMainWindow->bookmarkModel()->setIsForProject(inProject());
|
||||
pMainWindow->todoModel()->setIsForProject(inProject());
|
||||
|
||||
// if (pSettings->codeCompletion().clearWhenEditorHidden()
|
||||
// && !inProject()) {
|
||||
// reparse();
|
||||
|
@ -2711,7 +2713,7 @@ void Editor::reparseTodo()
|
|||
{
|
||||
if (!highlighter())
|
||||
return;
|
||||
pMainWindow->todoParser()->parseFile(mFilename);
|
||||
pMainWindow->todoParser()->parseFile(mFilename, inProject());
|
||||
}
|
||||
|
||||
void Editor::insertString(const QString &value, bool moveCursor)
|
||||
|
|
|
@ -1358,6 +1358,8 @@ void MainWindow::openProject(const QString &filename, bool openFiles)
|
|||
mDebugger->loadForProject(
|
||||
changeFileExt(mProject->filename(), PROJECT_DEBUG_EXT),
|
||||
mProject->directory());
|
||||
mTodoModel.setIsForProject(true);
|
||||
mTodoParser->parseFiles(mProject->unitFiles());
|
||||
|
||||
if (openFiles) {
|
||||
PProjectUnit unit = mProject->doAutoOpen();
|
||||
|
@ -4358,12 +4360,16 @@ void MainWindow::enableDebugActions()
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::onTodoParseStarted(const QString&)
|
||||
void MainWindow::onTodoParsingFile(const QString& filename)
|
||||
{
|
||||
mTodoModel.removeTodosForFile(filename);
|
||||
}
|
||||
void MainWindow::onTodoParseStarted()
|
||||
{
|
||||
mTodoModel.clear();
|
||||
}
|
||||
|
||||
void MainWindow::onTodoParsing(const QString& filename, int lineNo, int ch, const QString& line)
|
||||
void MainWindow::onTodoFound(const QString& filename, int lineNo, int ch, const QString& line)
|
||||
{
|
||||
mTodoModel.addItem(filename,lineNo,ch,line);
|
||||
}
|
||||
|
@ -4470,6 +4476,7 @@ void MainWindow::closeProject(bool refreshEditor)
|
|||
if (!mQuitting) {
|
||||
mBookmarkModel->setIsForProject(false);
|
||||
mDebugger->setIsForProject(false);
|
||||
mTodoModel.setIsForProject(false);
|
||||
// Clear error browser
|
||||
clearIssues();
|
||||
updateProjectView();
|
||||
|
@ -7111,6 +7118,11 @@ const PBookmarkModel &MainWindow::bookmarkModel() const
|
|||
return mBookmarkModel;
|
||||
}
|
||||
|
||||
TodoModel *MainWindow::todoModel()
|
||||
{
|
||||
return &mTodoModel;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_actionAdd_bookmark_triggered()
|
||||
{
|
||||
|
|
|
@ -196,6 +196,8 @@ public:
|
|||
|
||||
const PBookmarkModel &bookmarkModel() const;
|
||||
|
||||
TodoModel* todoModel();
|
||||
|
||||
Editor* openFile(const QString& filename, bool activate=true, QTabWidget* page=nullptr);
|
||||
void openProject(const QString& filename, bool openFiles = true);
|
||||
void changeOptions(const QString& widgetName=QString(), const QString& groupName=QString());
|
||||
|
@ -235,8 +237,9 @@ public slots:
|
|||
void onEditorTabContextMenu(QTabWidget* tabWidget, const QPoint& pos);
|
||||
void disableDebugActions();
|
||||
void enableDebugActions();
|
||||
void onTodoParseStarted(const QString& filename);
|
||||
void onTodoParsing(const QString& filename, int lineNo, int ch, const QString& line);
|
||||
void onTodoParsingFile(const QString& filename);
|
||||
void onTodoParseStarted();
|
||||
void onTodoFound(const QString& filename, int lineNo, int ch, const QString& line);
|
||||
void onTodoParseFinished();
|
||||
void setActiveBreakpoint(QString FileName, int Line, bool setFocus);
|
||||
void updateDPI(int oldDPI, int newDPI);
|
||||
|
|
|
@ -456,6 +456,15 @@ QList<PProjectUnit> Project::unitList()
|
|||
return units;
|
||||
}
|
||||
|
||||
QStringList Project::unitFiles()
|
||||
{
|
||||
QStringList units;
|
||||
foreach(PProjectUnit unit, mUnits) {
|
||||
units.append(unit->fileName());
|
||||
}
|
||||
return units;
|
||||
}
|
||||
|
||||
void Project::rebuildNodes()
|
||||
{
|
||||
mModel.beginUpdate();
|
||||
|
|
|
@ -230,6 +230,7 @@ public:
|
|||
Editor* unitEditor(const ProjectUnit* unit) const;
|
||||
|
||||
QList<PProjectUnit> unitList();
|
||||
QStringList unitFiles();
|
||||
|
||||
PProjectModelNode pointerToNode(ProjectModelNode * p, PProjectModelNode parent=PProjectModelNode());
|
||||
void rebuildNodes();
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
#include "mainwindow.h"
|
||||
#include "editor.h"
|
||||
#include "editorlist.h"
|
||||
#include "HighlighterManager.h"
|
||||
#include "qsynedit/Constants.h"
|
||||
|
||||
TodoParser::TodoParser(QObject *parent) : QObject(parent),
|
||||
mMutex(QMutex::Recursive)
|
||||
|
@ -27,7 +25,7 @@ TodoParser::TodoParser(QObject *parent) : QObject(parent),
|
|||
mThread = nullptr;
|
||||
}
|
||||
|
||||
void TodoParser::parseFile(const QString &filename)
|
||||
void TodoParser::parseFile(const QString &filename,bool isForProject)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mThread) {
|
||||
|
@ -42,10 +40,40 @@ void TodoParser::parseFile(const QString &filename)
|
|||
mThread = nullptr;
|
||||
}
|
||||
});
|
||||
if (!isForProject) {
|
||||
connect(mThread, &TodoThread::parseStarted,
|
||||
pMainWindow, &MainWindow::onTodoParseStarted);
|
||||
}
|
||||
connect(mThread, &TodoThread::parsingFile,
|
||||
pMainWindow, &MainWindow::onTodoParsingFile);
|
||||
connect(mThread, &TodoThread::todoFound,
|
||||
pMainWindow, &MainWindow::onTodoParsing);
|
||||
pMainWindow, &MainWindow::onTodoFound);
|
||||
connect(mThread, &TodoThread::parseFinished,
|
||||
pMainWindow, &MainWindow::onTodoParseFinished);
|
||||
mThread->start();
|
||||
}
|
||||
|
||||
void TodoParser::parseFiles(const QStringList &files)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mThread) {
|
||||
return;
|
||||
}
|
||||
mThread = new TodoThread(files);
|
||||
connect(mThread,&QThread::finished,
|
||||
[this] {
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mThread) {
|
||||
mThread->deleteLater();
|
||||
mThread = nullptr;
|
||||
}
|
||||
});
|
||||
connect(mThread, &TodoThread::parseStarted,
|
||||
pMainWindow, &MainWindow::onTodoParseStarted);
|
||||
connect(mThread, &TodoThread::parsingFile,
|
||||
pMainWindow, &MainWindow::onTodoParsingFile);
|
||||
connect(mThread, &TodoThread::todoFound,
|
||||
pMainWindow, &MainWindow::onTodoFound);
|
||||
connect(mThread, &TodoThread::parseFinished,
|
||||
pMainWindow, &MainWindow::onTodoParseFinished);
|
||||
mThread->start();
|
||||
|
@ -59,18 +87,39 @@ bool TodoParser::parsing() const
|
|||
TodoThread::TodoThread(const QString &filename, QObject *parent): QThread(parent)
|
||||
{
|
||||
mFilename = filename;
|
||||
mParseFiles = false;
|
||||
}
|
||||
|
||||
void TodoThread::run()
|
||||
TodoThread::TodoThread(const QStringList &files, QObject *parent): QThread(parent)
|
||||
{
|
||||
mFiles = files;
|
||||
mParseFiles = true;
|
||||
}
|
||||
|
||||
void TodoThread::parseFile()
|
||||
{
|
||||
QSynedit::PHighlighter highlighter = highlighterManager.getCppHighlighter();
|
||||
emit parseStarted(mFilename);
|
||||
auto action = finally([this]{
|
||||
emit parseStarted();
|
||||
doParseFile(mFilename,highlighter);
|
||||
emit parseFinished();
|
||||
});
|
||||
}
|
||||
|
||||
void TodoThread::parseFiles()
|
||||
{
|
||||
QSynedit::PHighlighter highlighter = highlighterManager.getCppHighlighter();
|
||||
emit parseStarted();
|
||||
foreach(const QString& filename,mFiles) {
|
||||
doParseFile(filename,highlighter);
|
||||
}
|
||||
emit parseFinished();
|
||||
}
|
||||
|
||||
void TodoThread::doParseFile(const QString &filename, QSynedit::PHighlighter highlighter)
|
||||
{
|
||||
emit parsingFile(filename);
|
||||
QStringList lines;
|
||||
if (!pMainWindow->editorList()->getContentFromOpenedEditor(mFilename,lines)) {
|
||||
return;
|
||||
if (!pMainWindow->editorList()->getContentFromOpenedEditor(filename,lines)) {
|
||||
lines = readFileToLines(filename);
|
||||
}
|
||||
QSynedit::PHighlighterAttribute commentAttr = highlighter->getAttribute(SYNS_AttrComment);
|
||||
|
||||
|
@ -82,6 +131,7 @@ void TodoThread::run()
|
|||
attr = highlighter->getTokenAttribute();
|
||||
if (attr == commentAttr) {
|
||||
QString token = highlighter->getToken();
|
||||
qDebug()<<token;
|
||||
int pos = token.indexOf("TODO:",0,Qt::CaseInsensitive);
|
||||
if (pos>=0) {
|
||||
emit todoFound(
|
||||
|
@ -95,29 +145,54 @@ void TodoThread::run()
|
|||
highlighter->next();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TodoThread::run()
|
||||
{
|
||||
if (mParseFiles) {
|
||||
parseFiles();
|
||||
} else {
|
||||
parseFile();
|
||||
}
|
||||
}
|
||||
|
||||
TodoModel::TodoModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
|
||||
mIsForProject=false;
|
||||
}
|
||||
|
||||
void TodoModel::addItem(const QString &filename, int lineNo, int ch, const QString &line)
|
||||
{
|
||||
beginInsertRows(QModelIndex(),mItems.count(),mItems.count());
|
||||
QList<PTodoItem> &items=getItems(mIsForProject);
|
||||
beginInsertRows(QModelIndex(),items.count(),items.count());
|
||||
PTodoItem item = std::make_shared<TodoItem>();
|
||||
item->filename = filename;
|
||||
item->lineNo = lineNo;
|
||||
item->ch = ch;
|
||||
item->line = line;
|
||||
mItems.append(item);
|
||||
items.append(item);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void TodoModel::removeTodosForFile(const QString &filename)
|
||||
{
|
||||
QList<PTodoItem> &items=getItems(mIsForProject);
|
||||
for(int i=items.count()-1;i>=0;i--) {
|
||||
PTodoItem item = items[i];
|
||||
if (item->filename==filename) {
|
||||
beginRemoveRows(QModelIndex(),i,i);
|
||||
items.removeAt(i);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TodoModel::clear()
|
||||
{
|
||||
beginResetModel();
|
||||
mItems.clear();
|
||||
QList<PTodoItem> &items=getItems(mIsForProject);
|
||||
items.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
@ -125,20 +200,46 @@ PTodoItem TodoModel::getItem(const QModelIndex &index)
|
|||
{
|
||||
if (!index.isValid())
|
||||
return PTodoItem();
|
||||
return mItems[index.row()];
|
||||
return getItems(mIsForProject)[index.row()];
|
||||
}
|
||||
|
||||
QList<PTodoItem> &TodoModel::getItems(bool forProject)
|
||||
{
|
||||
return forProject?mProjectItems:mItems;
|
||||
}
|
||||
|
||||
const QList<PTodoItem> &TodoModel::getConstItems(bool forProject) const
|
||||
{
|
||||
return forProject?mProjectItems:mItems;
|
||||
}
|
||||
|
||||
bool TodoModel::isForProject() const
|
||||
{
|
||||
return mIsForProject;
|
||||
}
|
||||
|
||||
void TodoModel::setIsForProject(bool newIsForProject)
|
||||
{
|
||||
if (mIsForProject!=newIsForProject) {
|
||||
beginResetModel();
|
||||
mIsForProject = newIsForProject;
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
|
||||
int TodoModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return mItems.count();
|
||||
const QList<PTodoItem> &items=getConstItems(mIsForProject);
|
||||
return items.count();
|
||||
}
|
||||
|
||||
QVariant TodoModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
const QList<PTodoItem> &items=getConstItems(mIsForProject);
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
if (role==Qt::DisplayRole) {
|
||||
PTodoItem item = mItems[index.row()];
|
||||
PTodoItem item = items[index.row()];
|
||||
switch(index.column()) {
|
||||
case 0:
|
||||
return item->filename;
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <QThread>
|
||||
#include <QMutex>
|
||||
#include <QAbstractListModel>
|
||||
#include "HighlighterManager.h"
|
||||
#include "qsynedit/Constants.h"
|
||||
|
||||
struct TodoItem {
|
||||
QString filename;
|
||||
|
@ -37,20 +39,25 @@ public:
|
|||
explicit TodoModel(QObject* parent=nullptr);
|
||||
void addItem(const QString& filename, int lineNo,
|
||||
int ch, const QString& line);
|
||||
void removeTodosForFile(const QString& filename);
|
||||
void clear();
|
||||
PTodoItem getItem(const QModelIndex& index);
|
||||
private:
|
||||
QList<PTodoItem> &getItems(bool forProject);
|
||||
const QList<PTodoItem> &getConstItems(bool forProject) const;
|
||||
private:
|
||||
QList<PTodoItem> mItems;
|
||||
QList<PTodoItem> mProjectItems;
|
||||
bool mIsForProject;
|
||||
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
int rowCount(const QModelIndex &parent) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
// QAbstractItemModel interface
|
||||
public:
|
||||
int columnCount(const QModelIndex &parent) const override;
|
||||
bool isForProject() const;
|
||||
void setIsForProject(bool newIsForProject);
|
||||
};
|
||||
|
||||
class TodoThread: public QThread
|
||||
|
@ -58,12 +65,20 @@ class TodoThread: public QThread
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit TodoThread(const QString& filename, QObject* parent = nullptr);
|
||||
explicit TodoThread(const QStringList& files, QObject* parent = nullptr);
|
||||
signals:
|
||||
void parseStarted(const QString& filename);
|
||||
void parseStarted();
|
||||
void parsingFile(const QString& fileName);
|
||||
void todoFound(const QString& filename, int lineNo, int ch, const QString& line);
|
||||
void parseFinished();
|
||||
private:
|
||||
void parseFile();
|
||||
void parseFiles();
|
||||
void doParseFile(const QString& filename, QSynedit::PHighlighter highlighter);
|
||||
private:
|
||||
QString mFilename;
|
||||
QStringList mFiles;
|
||||
bool mParseFiles;
|
||||
|
||||
// QThread interface
|
||||
protected:
|
||||
|
@ -77,7 +92,8 @@ class TodoParser : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit TodoParser(QObject *parent = nullptr);
|
||||
void parseFile(const QString& filename);
|
||||
void parseFile(const QString& filename,bool isForProject);
|
||||
void parseFiles(const QStringList& files);
|
||||
bool parsing() const;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue