- enhancement: base class dropdown list in new class dialog now works
This commit is contained in:
parent
4fa490253e
commit
1c3bf9000c
3
NEWS.md
3
NEWS.md
|
@ -5,7 +5,8 @@ Red Panda C++ Version 2.2
|
|||
- fix: Wrong charset name returned when saving file
|
||||
- fix: 'using =' / 'namespace =' not correctly handled
|
||||
- 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
|
||||
|
||||
|
|
|
@ -7963,7 +7963,7 @@ void MainWindow::on_actionNew_Class_triggered()
|
|||
{
|
||||
if (!mProject)
|
||||
return;
|
||||
NewClassDialog dialog;
|
||||
NewClassDialog dialog(mProject->cppParser());
|
||||
dialog.setPath(mProject->folder());
|
||||
if (dialog.exec()==QDialog::Accepted) {
|
||||
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("#define %1").arg(header_macro));
|
||||
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("");
|
||||
header.append("private:");
|
||||
|
|
|
@ -149,7 +149,7 @@ using StatementMap = QMultiMap<QString, PStatement>;
|
|||
struct 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 command; // identifier/name of statement "foo"
|
||||
QString args; // args "(int a,float b)"
|
||||
|
|
|
@ -431,13 +431,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
|
|||
case 0:
|
||||
if (order == Qt::SortOrder::AscendingOrder) {
|
||||
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(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
} else {
|
||||
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(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
|
@ -446,13 +446,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
|
|||
case 1:
|
||||
if (order == Qt::SortOrder::AscendingOrder) {
|
||||
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(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
} else {
|
||||
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(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
|
@ -461,13 +461,13 @@ void BookmarkModel::sort(int column, Qt::SortOrder order)
|
|||
case 2:
|
||||
if (order == Qt::SortOrder::AscendingOrder) {
|
||||
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(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
} else {
|
||||
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(mProjectBookmarks.begin(),mProjectBookmarks.end(),sorter);
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
#include "../iconsmanager.h"
|
||||
#include "../settings.h"
|
||||
#include <QFileDialog>
|
||||
#include <algorithm>
|
||||
|
||||
NewClassDialog::NewClassDialog(QWidget *parent) :
|
||||
NewClassDialog::NewClassDialog(PCppParser parser, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::NewClassDialog)
|
||||
ui(new Ui::NewClassDialog),
|
||||
mModel(parser)
|
||||
{
|
||||
setWindowFlag(Qt::WindowContextHelpButtonHint,false);
|
||||
ui->setupUi(this);
|
||||
|
@ -31,6 +33,7 @@ NewClassDialog::NewClassDialog(QWidget *parent) :
|
|||
connect(pIconsManager,&IconsManager::actionIconsUpdated,
|
||||
this, &NewClassDialog::onUpdateIcons);
|
||||
ui->txtClassName->setFocus();
|
||||
ui->cbBaseClass->setModel(&mModel);
|
||||
}
|
||||
|
||||
NewClassDialog::~NewClassDialog()
|
||||
|
@ -42,9 +45,9 @@ QString NewClassDialog::className() const
|
|||
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
|
||||
|
@ -105,3 +108,86 @@ void NewClassDialog::on_txtClassName_textChanged(const QString &/* arg1 */)
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -18,21 +18,42 @@
|
|||
#define NEWCLASSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "../parser/cppparser.h"
|
||||
#include <QAbstractListModel>
|
||||
|
||||
namespace Ui {
|
||||
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
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit NewClassDialog(QWidget *parent = nullptr);
|
||||
explicit NewClassDialog(PCppParser parser, QWidget *parent = nullptr);
|
||||
~NewClassDialog();
|
||||
|
||||
QString className() const;
|
||||
QString baseClass() const;
|
||||
PStatement baseClass() const;
|
||||
QString headerName() const;
|
||||
QString sourceName() const;
|
||||
QString path() const;
|
||||
|
@ -49,7 +70,8 @@ private slots:
|
|||
|
||||
private:
|
||||
Ui::NewClassDialog *ui;
|
||||
|
||||
QList<PStatement> mClasses;
|
||||
NewClassCandidatesModel mModel;
|
||||
private:
|
||||
void onUpdateIcons();
|
||||
|
||||
|
|
|
@ -48,7 +48,11 @@
|
|||
</widget>
|
||||
</item>
|
||||
<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 row="8" column="0" colspan="4">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
|
|
|
@ -208,7 +208,7 @@ void ASResource::buildAssignmentOperators(vector<const string*>* assignmentOpera
|
|||
assignmentOperators->emplace_back(&AS_LS_LS_LS_ASSIGN);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
|
||||
sort(preDefinitionHeaders->begin(), preDefinitionHeaders->end(), sortOnName);
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
|
Loading…
Reference in New Issue