- enhancement: base class dropdown list in new class dialog now works

This commit is contained in:
Roy Qu 2022-11-05 23:35:15 +08:00
parent 4fa490253e
commit 1c3bf9000c
8 changed files with 147 additions and 27 deletions

View File

@ -5,7 +5,8 @@ Red Panda C++ Version 2.2
- fix: Wrong charset name returned when saving file - fix: Wrong charset name returned when saving file
- fix: 'using =' / 'namespace =' not correctly handled - fix: 'using =' / 'namespace =' not correctly handled
- fix: Pressing '*' at begin of line will crash app - fix: Pressing '*' at begin of line will crash app
- enhancement: switch header/source - enhancement: switch header/source in editor's context menu
- enhancement: base class dropdown list in new class dialog now works
Red Panda C++ Version 2.1 Red Panda C++ Version 2.1

View File

@ -7963,7 +7963,7 @@ void MainWindow::on_actionNew_Class_triggered()
{ {
if (!mProject) if (!mProject)
return; return;
NewClassDialog dialog; NewClassDialog dialog(mProject->cppParser());
dialog.setPath(mProject->folder()); dialog.setPath(mProject->folder());
if (dialog.exec()==QDialog::Accepted) { if (dialog.exec()==QDialog::Accepted) {
QDir dir(dialog.path()); QDir dir(dialog.path());
@ -7997,7 +7997,14 @@ void MainWindow::on_actionNew_Class_triggered()
header.append(QString("#ifndef %1").arg(header_macro)); header.append(QString("#ifndef %1").arg(header_macro));
header.append(QString("#define %1").arg(header_macro)); header.append(QString("#define %1").arg(header_macro));
header.append(""); header.append("");
header.append(QString("class %1 {").arg(dialog.className())); if (dialog.baseClass()) {
header.append(QString("#include \"%1\"").arg(extractRelativePath(mProject->directory(),
dialog.baseClass()->fileName)));
header.append("");
header.append(QString("class %1 : public %2 {").arg(dialog.className(),
dialog.baseClass()->fullName));
} else
header.append(QString("class %1 {").arg(dialog.className()));
header.append("public:"); header.append("public:");
header.append(""); header.append("");
header.append("private:"); header.append("private:");

View File

@ -149,7 +149,7 @@ using StatementMap = QMultiMap<QString, PStatement>;
struct Statement { struct Statement {
// Statement(); // Statement();
// ~Statement(); // ~Statement();
std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, don't use auto pointer to prevent circular reference std::weak_ptr<Statement> parentScope; // parent class/struct/namespace scope, use weak pointer to prevent circular reference
QString type; // type "int" QString type; // type "int"
QString command; // identifier/name of statement "foo" QString command; // identifier/name of statement "foo"
QString args; // args "(int a,float b)" QString args; // args "(int a,float b)"

View File

@ -431,13 +431,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 0: case 0:
if (order == Qt::SortOrder::AscendingOrder) { if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) { auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b1->description,b2->description); return b1->description < b2->description;
}; };
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter); std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else { } else {
auto sorter=[](PBookmark b1,PBookmark b2) { auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b2->description,b1->description); return b2->description<b1->description;
}; };
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter); std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
@ -446,13 +446,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 1: case 1:
if (order == Qt::SortOrder::AscendingOrder) { if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) { auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b1->filename,b2->filename); return b1->filename<b2->filename;
}; };
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter); std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else { } else {
auto sorter=[](PBookmark b1,PBookmark b2) { auto sorter=[](PBookmark b1,PBookmark b2) {
return QString::compare(b2->filename,b1->filename); return b2->filename<b1->filename;
}; };
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter); std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
@ -461,13 +461,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
case 2: case 2:
if (order == Qt::SortOrder::AscendingOrder) { if (order == Qt::SortOrder::AscendingOrder) {
auto sorter=[](PBookmark b1,PBookmark b2) { auto sorter=[](PBookmark b1,PBookmark b2) {
return b1->line-b2->line; return b1->line<b2->line;
}; };
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter); std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
} else { } else {
auto sorter=[](PBookmark b1,PBookmark b2) { auto sorter=[](PBookmark b1,PBookmark b2) {
return b2->line-b1->line; return b2->line<b1->line;
}; };
std::sort(mBookmarks.begin(),mBookmarks.end(),sorter); std::sort(mBookmarks.begin(),mBookmarks.end(),sorter);
std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter); std::sort(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);

View File

@ -19,10 +19,12 @@
#include "../iconsmanager.h" #include "../iconsmanager.h"
#include "../settings.h" #include "../settings.h"
#include <QFileDialog> #include <QFileDialog>
#include <algorithm>
NewClassDialog::NewClassDialog(QWidget *parent) : NewClassDialog::NewClassDialog(PCppParser parser, QWidget *parent) :
QDialog(parent), QDialog(parent),
ui(new Ui::NewClassDialog) ui(new Ui::NewClassDialog),
mModel(parser)
{ {
setWindowFlag(Qt::WindowContextHelpButtonHint,false); setWindowFlag(Qt::WindowContextHelpButtonHint,false);
ui->setupUi(this); ui->setupUi(this);
@ -31,6 +33,7 @@ NewClassDialog::NewClassDialog(QWidget *parent) :
connect(pIconsManager,&IconsManager::actionIconsUpdated, connect(pIconsManager,&IconsManager::actionIconsUpdated,
this, &NewClassDialog::onUpdateIcons); this, &NewClassDialog::onUpdateIcons);
ui->txtClassName->setFocus(); ui->txtClassName->setFocus();
ui->cbBaseClass->setModel(&mModel);
} }
NewClassDialog::~NewClassDialog() NewClassDialog::~NewClassDialog()
@ -42,9 +45,9 @@ QString NewClassDialog::className() const
return ui->txtClassName->text(); return ui->txtClassName->text();
} }
QString NewClassDialog::baseClass() const PStatement NewClassDialog::baseClass() const
{ {
return ui->cbBaseClass->currentText(); return mModel.getCandidate(ui->cbBaseClass->currentIndex());
} }
QString NewClassDialog::headerName() const QString NewClassDialog::headerName() const
@ -105,3 +108,86 @@ void NewClassDialog::on_txtClassName_textChanged(const QString &/* arg1 */)
ui->txtSourceName->setText(ui->txtClassName->text().toLower()+".cpp"); ui->txtSourceName->setText(ui->txtClassName->text().toLower()+".cpp");
} }
NewClassCandidatesModel::NewClassCandidatesModel(PCppParser parser):QAbstractListModel(),
mParser(parser)
{
fillClasses();
}
PStatement NewClassCandidatesModel::getCandidate(int row) const
{
if (row<0)
return PStatement();
if (row==0)
return PStatement();
return mCandidates[row-1];
}
void NewClassCandidatesModel::fillClasses()
{
if (!mParser->enabled())
return;
if (!mParser->freeze())
return;
foreach( const PStatement& s, mParser->statementList().childrenStatements()) {
if (s->kind==StatementKind::skClass
&& s->inProject
&& !s->command.startsWith("_")
&& !s->command.contains("<")
&& !mClassNames.contains(s->fullName)) {
if (getFileType(s->fileName)==FileType::CHeader
|| getFileType(s->fileName)==FileType::CppHeader) {
mCandidates.append(s);
mClassNames.insert(s->fullName);
}
} else if (s->kind == StatementKind::skNamespace
&& !s->command.startsWith("_")
&& !s->command.contains("<")) {
fillClassesInNamespace(s);
}
}
mParser->unFreeze();
std::sort(mCandidates.begin(),mCandidates.end(),[](const PStatement& s1, const PStatement& s2){
return s1->fullName<s2->fullName;
});
}
void NewClassCandidatesModel::fillClassesInNamespace(PStatement ns)
{
foreach( const PStatement& s, mParser->statementList().childrenStatements(ns)) {
if (s->kind==StatementKind::skClass
&& s->inProject
&& !s->command.startsWith("_")
&& !s->command.contains("<")
&& !mClassNames.contains(s->fullName)) {
if (getFileType(s->fileName)==FileType::CHeader
|| getFileType(s->fileName)==FileType::CppHeader) {
mCandidates.append(s);
mClassNames.insert(s->fullName);
}
} else if (s->kind == StatementKind::skNamespace
&& !s->command.startsWith("_")
&& !s->command.contains("<")) {
fillClassesInNamespace(s);
}
}
}
int NewClassCandidatesModel::rowCount(const QModelIndex &/*parent*/) const
{
return mCandidates.count()+1;
}
QVariant NewClassCandidatesModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (role==Qt::DisplayRole) {
if (index.row()==0)
return "";
return mCandidates[index.row()-1]->fullName;
}
return QVariant();
}

View File

@ -18,21 +18,42 @@
#define NEWCLASSDIALOG_H #define NEWCLASSDIALOG_H
#include <QDialog> #include <QDialog>
#include "../parser/cppparser.h"
#include <QAbstractListModel>
namespace Ui { namespace Ui {
class NewClassDialog; class NewClassDialog;
} }
class NewClassCandidatesModel: public QAbstractListModel {
Q_OBJECT
public:
explicit NewClassCandidatesModel(PCppParser parser);
PStatement getCandidate(int row) const;
private:
void fillClasses();
void fillClassesInNamespace(PStatement ns);
private:
PCppParser mParser;
QVector<PStatement> mCandidates;
QSet<QString> mClassNames;
// QAbstractItemModel interface
public:
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
};
class NewClassDialog : public QDialog class NewClassDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit NewClassDialog(QWidget *parent = nullptr); explicit NewClassDialog(PCppParser parser, QWidget *parent = nullptr);
~NewClassDialog(); ~NewClassDialog();
QString className() const; QString className() const;
QString baseClass() const; PStatement baseClass() const;
QString headerName() const; QString headerName() const;
QString sourceName() const; QString sourceName() const;
QString path() const; QString path() const;
@ -49,7 +70,8 @@ private slots:
private: private:
Ui::NewClassDialog *ui; Ui::NewClassDialog *ui;
QList<PStatement> mClasses;
NewClassCandidatesModel mModel;
private: private:
void onUpdateIcons(); void onUpdateIcons();

View File

@ -48,7 +48,11 @@
</widget> </widget>
</item> </item>
<item row="1" column="2" colspan="2"> <item row="1" column="2" colspan="2">
<widget class="QComboBox" name="cbBaseClass"/> <widget class="QComboBox" name="cbBaseClass">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item> </item>
<item row="8" column="0" colspan="4"> <item row="8" column="0" colspan="4">
<widget class="QWidget" name="widget" native="true"> <widget class="QWidget" name="widget" native="true">

View File

@ -208,7 +208,7 @@ void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOpera
assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN); assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN);
assert(assignmentOperators->size() < elements); assert(assignmentOperators->size() < elements);
sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength); sort(assignmentOperators->begin(), assignmentOperators->end(), sortOnLength);
} }
/** /**
@ -228,7 +228,7 @@ void ASResource::buildCastOperators(vector<const string*>* castOperators)
castOperators->emplace_back(&AS_STATIC_CAST); castOperators->emplace_back(&AS_STATIC_CAST);
assert(castOperators->size() < elements); assert(castOperators->size() < elements);
sort(castOperators->begin(), castOperators->end(), sortOnName); sort(castOperators->begin(), castOperators->end(), sortOnName);
} }
/** /**
@ -295,7 +295,7 @@ void ASResource::buildHeaders(vector<const string*>* headers, int fileType, bool
} }
assert(headers->size() < elements); assert(headers->size() < elements);
sort(headers->begin(), headers->end(), sortOnName); sort(headers->begin(), headers->end(), sortOnName);
} }
/** /**
@ -369,7 +369,7 @@ void ASResource::buildNonAssignmentOperators(vector<const string*>* nonAssignmen
nonAssignmentOperators->emplace_back(&AS_LAMBDA); nonAssignmentOperators->emplace_back(&AS_LAMBDA);
assert(nonAssignmentOperators->size() < elements); assert(nonAssignmentOperators->size() < elements);
sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength); sort(nonAssignmentOperators->begin(), nonAssignmentOperators->end(), sortOnLength);
} }
/** /**
@ -425,7 +425,7 @@ void ASResource::buildNonParenHeaders(vector<const string*>* nonParenHeaders, in
} }
assert(nonParenHeaders->size() < elements); assert(nonParenHeaders->size() < elements);
sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName); sort(nonParenHeaders->begin(), nonParenHeaders->end(), sortOnName);
} }
/** /**
@ -489,7 +489,7 @@ void ASResource::buildOperators(vector<const string*>* operators, int fileType)
} }
assert(operators->size() < elements); assert(operators->size() < elements);
sort(operators->begin(), operators->end(), sortOnLength); sort(operators->begin(), operators->end(), sortOnLength);
} }
/** /**
@ -527,7 +527,7 @@ void ASResource::buildPreBlockStatements(vector<const string*>* preBlockStatemen
} }
assert(preBlockStatements->size() < elements); assert(preBlockStatements->size() < elements);
sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName); sort(preBlockStatements->begin(), preBlockStatements->end(), sortOnName);
} }
/** /**
@ -567,7 +567,7 @@ void ASResource::buildPreCommandHeaders(vector<const string*>* preCommandHeaders
} }
assert(preCommandHeaders->size() < elements); assert(preCommandHeaders->size() < elements);
sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName); sort(preCommandHeaders->begin(), preCommandHeaders->end(), sortOnName);
} }
/** /**
@ -604,7 +604,7 @@ void ASResource::buildPreDefinitionHeaders(vector<const string*>* preDefinitionH
} }
assert(preDefinitionHeaders->size() < elements); assert(preDefinitionHeaders->size() < elements);
sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName); sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
} }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *