diff --git a/RedPandaIDE/RedPandaIDE.pro b/RedPandaIDE/RedPandaIDE.pro index e9e97ff5..2cdc45e1 100644 --- a/RedPandaIDE/RedPandaIDE.pro +++ b/RedPandaIDE/RedPandaIDE.pro @@ -46,6 +46,7 @@ SOURCES += \ settingsdialog/editorautosavewidget.cpp \ settingsdialog/editorcodecompletionwidget.cpp \ settingsdialog/editormiscwidget.cpp \ + settingsdialog/editorsnippetwidget.cpp \ settingsdialog/editortooltipswidget.cpp \ settingsdialog/formattergeneralwidget.cpp \ settingsdialog/projectcompileparamaterswidget.cpp \ @@ -146,6 +147,7 @@ HEADERS += \ settingsdialog/editorautosavewidget.h \ settingsdialog/editorcodecompletionwidget.h \ settingsdialog/editormiscwidget.h \ + settingsdialog/editorsnippetwidget.h \ settingsdialog/editortooltipswidget.h \ settingsdialog/formattergeneralwidget.h \ settingsdialog/projectcompileparamaterswidget.h \ @@ -219,6 +221,7 @@ FORMS += \ settingsdialog/editorautosavewidget.ui \ settingsdialog/editorcodecompletionwidget.ui \ settingsdialog/editormiscwidget.ui \ + settingsdialog/editorsnippetwidget.ui \ settingsdialog/editortooltipswidget.ui \ settingsdialog/formattergeneralwidget.ui \ settingsdialog/projectcompileparamaterswidget.ui \ diff --git a/RedPandaIDE/codesnippetsmanager.cpp b/RedPandaIDE/codesnippetsmanager.cpp index cad13ba0..429709f9 100644 --- a/RedPandaIDE/codesnippetsmanager.cpp +++ b/RedPandaIDE/codesnippetsmanager.cpp @@ -49,8 +49,19 @@ void CodeSnippetsManager::save() } } -void CodeSnippetsManager::addSnippet(const QString &caption, const QString &prefix, const QString &code, const QString &description, int menuSection) +const QList &CodeSnippetsManager::snippets() const { + return mSnippets; +} + +void CodeSnippetsManager::setSnippets(const QList &newSnippets) +{ + mSnippets = newSnippets; +} + +void CodeSnippetsModel::addSnippet(const QString &caption, const QString &prefix, const QString &code, const QString &description, int menuSection) +{ + beginInsertRows(QModelIndex(),mSnippets.count(),mSnippets.count()); PCodeSnippet snippet = std::make_shared(); snippet->caption = caption; snippet->prefix = prefix; @@ -58,22 +69,22 @@ void CodeSnippetsManager::addSnippet(const QString &caption, const QString &pref snippet->desc = description; snippet->section = menuSection; mSnippets.append(snippet); + endInsertRows(); } -void CodeSnippetsManager::remove(int index) +void CodeSnippetsModel::remove(int index) { Q_ASSERT(index>=0 && index &CodeSnippetsManager::snippets() const -{ - return mSnippets; + endRemoveRows(); } int CodeSnippetsModel::rowCount(const QModelIndex &parent) const @@ -86,9 +97,52 @@ int CodeSnippetsModel::columnCount(const QModelIndex &parent) const return 4; } +QVariant CodeSnippetsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + if (role==Qt::DisplayRole) { + int row = index.row(); + PCodeSnippet snippet = mSnippets[row]; + switch(index.column()) { + case 0: + return snippet->caption; + case 1: + return snippet->prefix; + case 2: + return snippet->desc; + case 3: + return snippet->section; + } + } + return QVariant(); +} + bool CodeSnippetsModel::setData(const QModelIndex &index, const QVariant &value, int role) { - + if (!index.isValid()) { + return false; + } + if (role==Qt::EditRole) { + int row = index.row(); + PCodeSnippet snippet = mSnippets[row]; + switch(index.column()) { + case 0: + snippet->caption = value.toString(); + return true; + case 1: + snippet->prefix = value.toString(); + return true; + case 2: + snippet->desc = value.toString(); + return true; + case 3: + snippet->section = value.toInt(); + return true; + } + } + return false; } QVariant CodeSnippetsModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -107,3 +161,20 @@ QVariant CodeSnippetsModel::headerData(int section, Qt::Orientation orientation, } return QVariant(); } + +Qt::ItemFlags CodeSnippetsModel::flags(const QModelIndex &) const +{ + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +const QList &CodeSnippetsModel::snippets() const +{ + return mSnippets; +} + +void CodeSnippetsModel::updateSnippets(const QList &snippets) +{ + beginResetModel(); + mSnippets = snippets; + endResetModel(); +} diff --git a/RedPandaIDE/codesnippetsmanager.h b/RedPandaIDE/codesnippetsmanager.h index 11420242..13925680 100644 --- a/RedPandaIDE/codesnippetsmanager.h +++ b/RedPandaIDE/codesnippetsmanager.h @@ -3,6 +3,34 @@ #include #include "parser/parserutils.h" +#include + +class CodeSnippetsModel: public QAbstractListModel { + Q_OBJECT +public: + void addSnippet( + const QString& caption, + const QString& prefix, + const QString& code, + const QString& description, + int menuSection); + void remove(int index); + void clear(); + + // QAbstractItemModel interface +public: + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + const QList &snippets() const; + void updateSnippets(const QList& snippets); + +private: + QList mSnippets; +}; class CodeSnippetsManager : public QObject { @@ -12,21 +40,16 @@ public: void load(); void save(); - void addSnippet( - const QString& caption, - const QString& prefix, - const QString& code, - const QString& description, - int menuSection); - void remove(int index); - void clear(); const QList &snippets() const; + void setSnippets(const QList &newSnippets); + signals: + private: QList mSnippets; - -private: }; +using PCodeSnippetManager = std::shared_ptr; + #endif // CODESNIPPETSMANAGER_H diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index fd024424..98531715 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -125,6 +125,8 @@ MainWindow::MainWindow(QWidget *parent) mSymbolUsageManager = std::make_shared(); mSymbolUsageManager->load(); + mCodeSnippetManager = std::make_shared(); + mCodeSnippetManager->load(); mSearchResultTreeModel = std::make_shared(&mSearchResultModel); mSearchResultListModel = std::make_shared(&mSearchResultModel); mSearchViewDelegate = std::make_shared(mSearchResultTreeModel); @@ -3748,6 +3750,11 @@ void MainWindow::on_classBrowser_doubleClicked(const QModelIndex &index) } } +PCodeSnippetManager &MainWindow::codeSnippetManager() +{ + return mCodeSnippetManager; +} + PSymbolUsageManager &MainWindow::symbolUsageManager() { return mSymbolUsageManager; diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index 032bb517..5beb8526 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -12,6 +12,7 @@ #include "widgets/functiontooltipwidget.h" #include "caretlist.h" #include "symbolusagemanager.h" +#include "codesnippetsmanager.h" QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } @@ -116,6 +117,8 @@ public: PSymbolUsageManager &symbolUsageManager(); + PCodeSnippetManager &codeSnippetManager(); + public slots: void onCompileLog(const QString& msg); void onCompileIssue(PCompileIssue issue); @@ -383,6 +386,7 @@ private: ClassBrowserModel mClassBrowserModel; std::shared_ptr> mStatementColors; PSymbolUsageManager mSymbolUsageManager; + PCodeSnippetManager mCodeSnippetManager; bool mCheckSyntaxInBack; bool mOpenClosingBottomPanel; diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index f010740f..0d30f2b0 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -13,7 +13,7 @@ struct CodeSnippet { int section; //Section in the menu }; -using PCodeIns = std::shared_ptr; +using PCodeSnippet = std::shared_ptr; // preprocess/ macro define struct Define { diff --git a/RedPandaIDE/settingsdialog/editorsnippetwidget.cpp b/RedPandaIDE/settingsdialog/editorsnippetwidget.cpp new file mode 100644 index 00000000..b609b97b --- /dev/null +++ b/RedPandaIDE/settingsdialog/editorsnippetwidget.cpp @@ -0,0 +1,70 @@ +#include "editorsnippetwidget.h" +#include "ui_editorsnippetwidget.h" +#include "../mainwindow.h" +#include "../codesnippetsmanager.h" + +EditorSnippetWidget::EditorSnippetWidget(const QString& name, const QString& group, + QWidget *parent) : + SettingsWidget(name,group,parent), + ui(new Ui::EditorSnippetWidget) +{ + mUpdatingCode = false; + ui->setupUi(this); + ui->tblSnippets->setModel(&mModel); + connect(ui->editCode, &Editor::changed, + [this] { + if (mUpdatingCode) + return; + QModelIndex index = ui->tblSnippets->currentIndex(); + if (!index.isValid()) + return; + PCodeSnippet snippet = mModel.snippets()[index.row()]; + snippet->code = ui->editCode->lines()->text(); + }); +} + +EditorSnippetWidget::~EditorSnippetWidget() +{ + delete ui; +} + +void EditorSnippetWidget::doLoad() +{ + mModel.updateSnippets(pMainWindow->codeSnippetManager()->snippets()); +} + +void EditorSnippetWidget::doSave() +{ + pMainWindow->codeSnippetManager()->setSnippets(mModel.snippets()); + pMainWindow->codeSnippetManager()->save(); +} + +void EditorSnippetWidget::on_tblSnippets_clicked(const QModelIndex &index) +{ + if (!index.isValid()) + return; + mUpdatingCode = true; + PCodeSnippet snippet = mModel.snippets()[index.row()]; + ui->editCode->lines()->setText(snippet->code); + mUpdatingCode = false; +} + + +void EditorSnippetWidget::on_btnAdd_triggered(QAction *arg1) +{ + mModel.addSnippet(QString("Code %1").arg(getNewFileNumber()), + "", + "", + "", + -1); +} + + +void EditorSnippetWidget::on_btnRemove_triggered(QAction *arg1) +{ + QModelIndex index = ui->tblSnippets->currentIndex(); + if (!index.isValid()) + return; + mModel.remove(index.row()); +} + diff --git a/RedPandaIDE/settingsdialog/editorsnippetwidget.h b/RedPandaIDE/settingsdialog/editorsnippetwidget.h new file mode 100644 index 00000000..660e8f30 --- /dev/null +++ b/RedPandaIDE/settingsdialog/editorsnippetwidget.h @@ -0,0 +1,35 @@ +#ifndef EDITORSNIPPETWIDGET_H +#define EDITORSNIPPETWIDGET_H + +#include +#include "settingswidget.h" +#include "../codesnippetsmanager.h" + +namespace Ui { +class EditorSnippetWidget; +} + +class EditorSnippetWidget : public SettingsWidget +{ + Q_OBJECT + +public: + explicit EditorSnippetWidget(const QString& name, const QString& group, QWidget *parent = nullptr); + ~EditorSnippetWidget(); + +private: + Ui::EditorSnippetWidget *ui; + CodeSnippetsModel mModel; +private: + bool mUpdatingCode; + // SettingsWidget interface +protected: + void doLoad() override; + void doSave() override; +private slots: + void on_tblSnippets_clicked(const QModelIndex &index); + void on_btnAdd_triggered(QAction *arg1); + void on_btnRemove_triggered(QAction *arg1); +}; + +#endif // EDITORSNIPPETWIDGET_H diff --git a/RedPandaIDE/settingsdialog/editorsnippetwidget.ui b/RedPandaIDE/settingsdialog/editorsnippetwidget.ui new file mode 100644 index 00000000..fcc5bda9 --- /dev/null +++ b/RedPandaIDE/settingsdialog/editorsnippetwidget.ui @@ -0,0 +1,94 @@ + + + EditorSnippetWidget + + + + 0 + 0 + 932 + 574 + + + + Form + + + + + + Qt::Vertical + + + + + + + + + + + + + Add + + + + :/icons/images/newlook24/002-add.png:/icons/images/newlook24/002-add.png + + + + + + + Remove + + + + :/icons/images/newlook24/008-close.png:/icons/images/newlook24/008-close.png + + + + + + + Qt::Vertical + + + + 20 + 159 + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + + + Editor + QFrame +
editor.h
+ 1 +
+
+ + + + +
diff --git a/RedPandaIDE/settingsdialog/settingsdialog.cpp b/RedPandaIDE/settingsdialog/settingsdialog.cpp index 18b0ecc0..d2eb21c1 100644 --- a/RedPandaIDE/settingsdialog/settingsdialog.cpp +++ b/RedPandaIDE/settingsdialog/settingsdialog.cpp @@ -12,6 +12,7 @@ #include "editorsymbolcompletionwidget.h" #include "editortooltipswidget.h" #include "editorautosavewidget.h" +#include "editorsnippetwidget.h" #include "editormiscwidget.h" #include "environmentappearencewidget.h" #include "executorgeneralwidget.h" @@ -126,6 +127,10 @@ PSettingsDialog SettingsDialog::optionDialog() widget->init(); dialog->addWidget(widget); + widget = new EditorSnippetWidget(tr("Snippet"),tr("Editor")); + widget->init(); + dialog->addWidget(widget); + widget = new EditorSyntaxCheckWidget(tr("Auto Syntax Checking"),tr("Editor")); widget->init(); dialog->addWidget(widget); diff --git a/RedPandaIDE/widgets/codecompletionpopup.cpp b/RedPandaIDE/widgets/codecompletionpopup.cpp index a9f690ad..9631f1b2 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.cpp +++ b/RedPandaIDE/widgets/codecompletionpopup.cpp @@ -471,7 +471,7 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin if (mShowCodeIns) { //add custom code templates - foreach (const PCodeIns& codeIn,mCodeInsList) { + foreach (const PCodeSnippet& codeIn,mCodeInsList) { PStatement statement = std::make_shared(); statement->command = codeIn->prefix; statement->kind = StatementKind::skUserCodeIn; diff --git a/RedPandaIDE/widgets/codecompletionpopup.h b/RedPandaIDE/widgets/codecompletionpopup.h index aba5d2e0..b0813ef0 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.h +++ b/RedPandaIDE/widgets/codecompletionpopup.h @@ -77,7 +77,7 @@ private: private: CodeCompletionListView * mListView; CodeCompletionListModel* mModel; - QList mCodeInsList; //(Code template list) + QList mCodeInsList; //(Code template list) //QList mCodeInsStatements; //temporary (user code template) statements created when show code suggestion StatementList mFullCompletionStatementList; StatementList mCompletionStatementList;