work save

This commit is contained in:
royqh1979@gmail.com 2021-09-30 20:10:48 +08:00
parent a0ea72071c
commit c59e2c6667
12 changed files with 296 additions and 36 deletions

View File

@ -16,12 +16,55 @@ CodeSnippetsManager::CodeSnippetsManager(QObject *parent) : QObject(parent)
void CodeSnippetsManager::load()
{
//if config file not exists, copy it from data
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_CODESNIPPET_FILE;
if (!fileExists(filename)) {
QString defaultFilename = ":/config/codesnippets.json";
if (!QFile::copy(
defaultFilename,
filename)) {
QMessageBox::critical(nullptr,
tr("Load default code snippets failed"),
tr("Can't copy default code snippets '%1' to '%2'.")
.arg(defaultFilename)
.arg(filename));
}
}
//read config file
QFile file(filename);
if (!file.open(QFile::ReadOnly)) {
QMessageBox::critical(nullptr,
tr("Read code snippets failed"),
tr("Can't open code snippet file '%1' for read.")
.arg(filename));
}
QByteArray json = file.readAll();
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(json,&error);
if (error.error != QJsonParseError::NoError) {
QMessageBox::critical(nullptr,
tr("Read code snippets failed"),
tr("Read code snippet file '%1' failed:%2")
.arg(filename)
.arg(error.errorString()));
}
mSnippets.clear();
QJsonArray array = doc.array();
foreach (const QJsonValue& value,array) {
QJsonObject object = value.toObject();
PCodeSnippet snippet = std::make_shared<CodeSnippet>();
snippet->caption = object["caption"].toString();
snippet->prefix = object["prefix"].toString();
snippet->code = object["code"].toString();
snippet->desc = object["description"].toString();
snippet->section = object["section"].toInt();
mSnippets.append(snippet);
}
}
void CodeSnippetsManager::save()
{
QString filename = pSettings->dirs().config() + DEV_CODESNIPPET_FILE;
QString filename = includeTrailingPathDelimiter(pSettings->dirs().config()) + DEV_CODESNIPPET_FILE;
QFile file(filename);
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
QMessageBox::critical(nullptr,
@ -87,12 +130,18 @@ void CodeSnippetsModel::clear()
endRemoveRows();
}
int CodeSnippetsModel::rowCount(const QModelIndex &parent) const
QModelIndex CodeSnippetsModel::lastSnippetCaption()
{
Q_ASSERT(mSnippets.count()>0);
return createIndex(mSnippets.count()-1,0);
}
int CodeSnippetsModel::rowCount(const QModelIndex &) const
{
return mSnippets.count();
}
int CodeSnippetsModel::columnCount(const QModelIndex &parent) const
int CodeSnippetsModel::columnCount(const QModelIndex &) const
{
return 4;
}

View File

@ -16,6 +16,7 @@ public:
int menuSection);
void remove(int index);
void clear();
QModelIndex lastSnippetCaption();
// QAbstractItemModel interface
public:

View File

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/config">
<file alias="autolink.json">resources/autolink.json</file>
<file alias="codesnippets.json">resources/codesnippets.json</file>
</qresource>
</RCC>

View File

@ -1718,6 +1718,92 @@ void Editor::insertString(const QString &value, bool moveCursor)
}
}
void Editor::insertCodeSnippet(const QString &code)
{
clearUserCodeInTabStops();
mXOffsetSince = 0;
mTabStopBegin = -1;
mTabStopEnd = -1;
mTabStopY =0;
mLineBeforeTabStop = "";
mLineAfterTabStop = "";
QStringList sl;
QString newSl;
// prevent lots of repaints
beginUpdate();
auto action = finally([this]{
endUpdate();
});
fText.BeginUpdate;
try
sl.Text:=ParseMacros(Code);
lastI:=0;
spaceCount := Length(Text.GetLeftSpacing(
Text.LeftSpacesEx(fText.LineText,True), True));
for i:=0 to sl.Count -1 do begin
lastPos := 0;
s:= sl[i];
if i>0 then
lastPos := -spaceCount;
while True do begin
insertPos := Pos(USER_CODE_IN_INSERT_POS,s);
if insertPos = 0 then // no %INSERT% macro in this line now
break;
System.new(p);
Delete(s,insertPos,Length(USER_CODE_IN_INSERT_POS));
dec(insertPos);
p.x:=insertPos - lastPos;
p.endX := p.x;
p.y:=i-lastI;
lastPos := insertPos;
lastI:=i;
fUserCodeInTabStops.Add(p);
end;
while True do begin
insertPos := Pos(USER_CODE_IN_REPL_POS_BEGIN,s);
if insertPos = 0 then // no %INSERT% macro in this line now
break;
System.new(p);
Delete(s,insertPos,Length(USER_CODE_IN_REPL_POS_BEGIN));
dec(insertPos);
p.x:=insertPos - lastPos;
insertEndPos := insertPos + Pos(USER_CODE_IN_REPL_POS_END,copy(s,insertPos+1,MaxInt));
if insertEndPos <= insertPos then begin
p.endX := length(s);
end else begin
Delete(s,insertEndPos,Length(USER_CODE_IN_REPL_POS_END));
dec(insertEndPos);
p.endX := insertEndPos - lastPos;
end;
p.y:=i-lastI;
lastPos := insertEndPos;
lastI:=i;
fUserCodeInTabStops.Add(p);
end;
newSl.Add(s);
end;
CursorPos := Text.CaretXY;
s:=newSl.Text;
if EndsStr(#13#10,s) then
Delete(s,Length(s)-1,2)
else if EndsStr(#10, s) then
Delete(s,Length(s),1);
fText.SelText := s;
Text.CaretXY := CursorPos; //restore cursor pos before insert
if fUserCodeInTabStops.Count > 0 then begin
fTabStopBegin :=Text.CaretX;
fTabStopEnd := Text.CaretX;
PopUserCodeInTabStops;
end;
if Code <> '' then
fLastIdCharPressed := 0;
// prevent lots of repaints
finally
fText.EndUpdate;
end;
}
void Editor::showCompletion(bool autoComplete)
{
if (!pSettings->codeCompletion().enabled())
@ -1766,7 +1852,10 @@ void Editor::showCompletion(bool autoComplete)
mCompletionPopup->setRecordUsage(pSettings->codeCompletion().recordUsage());
mCompletionPopup->setSortByScope(pSettings->codeCompletion().sortByScope());
mCompletionPopup->setShowKeywords(pSettings->codeCompletion().showKeywords());
mCompletionPopup->setShowCodeIns(pSettings->codeCompletion().showCodeIns());
mCompletionPopup->setShowCodeSnippets(pSettings->codeCompletion().showCodeIns());
if (pSettings->codeCompletion().showCodeIns()) {
mCompletionPopup->setCodeSnippets(pMainWindow->codeSnippetManager()->snippets());
}
mCompletionPopup->setIgnoreCase(pSettings->codeCompletion().ignoreCase());
mCompletionPopup->resize(pSettings->codeCompletion().width(),
pSettings->codeCompletion().height());
@ -1902,7 +1991,7 @@ void Editor::completionInsert(bool appendFunc)
return;
if (pSettings->codeCompletion().recordUsage()
&& statement->kind != StatementKind::skUserCodeIn) {
&& statement->kind != StatementKind::skUserCodeSnippet) {
statement->usageCount+=1;
pMainWindow->symbolUsageManager()->updateUsage(statement->fullName,
statement->usageCount);
@ -1929,8 +2018,9 @@ void Editor::completionInsert(bool appendFunc)
}
// ... by replacing the selection
if (statement->kind == StatementKind::skUserCodeIn) { // it's a user code template
//insertUserCodeIn(Statement->value);
if (statement->kind == StatementKind::skUserCodeSnippet) { // it's a user code template
// insertUserCodeIn(Statement->value);
insertCodeSnippet(statement->value);
} else {
if (
(statement->kind == StatementKind::skKeyword

View File

@ -371,7 +371,7 @@ void MainWindow::updateEditorColorSchemes()
item = pColorManager->getItem(schemeName, SYNS_AttrReservedWord);
if (item) {
mStatementColors->insert(StatementKind::skKeyword,item->foreground());
mStatementColors->insert(StatementKind::skUserCodeIn,item->foreground());
mStatementColors->insert(StatementKind::skUserCodeSnippet,item->foreground());
}
item = pColorManager->getItem(schemeName, SYNS_AttrString);
if (item) {

View File

@ -60,7 +60,7 @@ enum StatementKind {
skNamespace,
skNamespaceAlias,
skBlock,
skUserCodeIn, // user code template
skUserCodeSnippet, // user code template
skKeyword, // keywords
skGlobalVariable,
skLocalVariable,

View File

@ -0,0 +1,65 @@
[
{
"caption": "for(;;)",
"code": "for(%REPL_BEGIN%int i=0%REPL_END%;%REPL_BEGIN%i<=0%REPL_END%;%REPL_BEGIN%i++%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}",
"description": "",
"prefix": "for(;;)",
"section": -1
},
{
"caption": "if else",
"code": "if(%REPL_BEGIN%1%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}else{\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}",
"description": "",
"prefix": "if_else",
"section": -1
},
{
"caption": "if else if",
"code": "if(%REPL_BEGIN%1%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}else if(%REPL_BEGIN%1%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}else{\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}",
"description": "",
"prefix": "if_else_if",
"section": -1
},
{
"caption": "if()",
"code": "if(%REPL_BEGIN%1%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}",
"description": "",
"prefix": "if()",
"section": -1
},
{
"caption": "while()",
"code": "while(%REPL_BEGIN%1%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}",
"description": "",
"prefix": "while()",
"section": -1
},
{
"caption": "class{;;}",
"code": "class %REPL_BEGIN%YourClassName%REPL_END% {\r\n\t\t%REPL_BEGIN%int YourVar%REPL_END%;\r\n\tpublic:\r\n\t\t%REPL_BEGIN%YourClassName%REPL_END%() {\r\n\r\n\t\t}\r\n\t\t~%REPL_BEGIN%YourClassName%REPL_END%() {\r\n\r\n\t\t}\r\n\t\t%REPL_BEGIN%void YourMethodOrFunction%REPL_END%() {\r\n\r\n\t\t}\r\n};",
"description": "",
"prefix": "class{;;}",
"section": -1
},
{
"caption": "switch(){}",
"code": "switch (%REPL_BEGIN%1%REPL_END%) {\r\n\tcase %REPL_BEGIN%1%REPL_END%:\r\n\t\t%REPL_BEGIN%//TODO%REPL_END%\r\n\t\tbreak;\r\n\tcase %REPL_BEGIN%2%REPL_END%:\r\n\t\t%REPL_BEGIN%//TODO%REPL_END%\r\n\t\tbreak;\r\n\tdefault:\r\n\t\t%REPL_BEGIN%//TODO%REPL_END%\r\n\t\tbreak;\r\n}",
"description": "",
"prefix": "switch(){}",
"section": -1
},
{
"caption": "do{}while()",
"code": "do{\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n}while(%REPL_BEGIN%1%REPL_END%);",
"description": "",
"prefix": "do{}while()",
"section": -1
},
{
"caption": "function()",
"code": "%REPL_BEGIN%int YourFunctionName%REPL_END%(%REPL_BEGIN%int YourParaments%REPL_END%){\r\n\t%REPL_BEGIN%//TODO%REPL_END%\r\n\treturn %REPL_BEGIN%0%REPL_END%;\r\n}",
"description": "",
"prefix": "function()",
"section": -1
}
]

View File

@ -3,6 +3,8 @@
#include "../mainwindow.h"
#include "../codesnippetsmanager.h"
#include <QItemSelectionModel>
EditorSnippetWidget::EditorSnippetWidget(const QString& name, const QString& group,
QWidget *parent) :
SettingsWidget(name,group,parent),
@ -20,6 +22,21 @@ EditorSnippetWidget::EditorSnippetWidget(const QString& name, const QString& gro
return;
PCodeSnippet snippet = mModel.snippets()[index.row()];
snippet->code = ui->editCode->lines()->text();
setSettingsChanged();
});
connect(ui->tblSnippets->selectionModel(), &QItemSelectionModel::currentChanged,
[this] {
QModelIndex index = ui->tblSnippets->currentIndex();
if (!index.isValid()) {
ui->editCode->setEnabled(false);
ui->editCode->lines()->clear();
} else {
mUpdatingCode = true;
ui->editCode->setEnabled(true);
PCodeSnippet snippet = mModel.snippets()[index.row()];
ui->editCode->lines()->setText(snippet->code);
mUpdatingCode = false;
}
});
}
@ -39,32 +56,22 @@ void EditorSnippetWidget::doSave()
pMainWindow->codeSnippetManager()->save();
}
void EditorSnippetWidget::on_tblSnippets_clicked(const QModelIndex &index)
void EditorSnippetWidget::on_btnAdd_clicked()
{
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()),
mModel.addSnippet(QString("").arg(getNewFileNumber()),
"",
"",
"",
-1);
ui->tblSnippets->setCurrentIndex(mModel.lastSnippetCaption());
ui->tblSnippets->edit(mModel.lastSnippetCaption());
}
void EditorSnippetWidget::on_btnRemove_triggered(QAction *arg1)
void EditorSnippetWidget::on_btnRemove_clicked()
{
QModelIndex index = ui->tblSnippets->currentIndex();
if (!index.isValid())
return;
mModel.remove(index.row());
}

View File

@ -27,9 +27,8 @@ 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);
void on_btnRemove_clicked();
void on_btnAdd_clicked();
};
#endif // EDITORSNIPPETWIDGET_H

View File

@ -21,12 +21,49 @@
</property>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTableView" name="tblSnippets"/>
<widget class="QTableView" name="tblSnippets">
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="textElideMode">
<enum>Qt::ElideNone</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="btnAdd">
<property name="text">

View File

@ -32,8 +32,9 @@ void SymbolUsageManager::load()
if (error.error != QJsonParseError::NoError) {
QMessageBox::critical(nullptr,
tr("Load symbol usage info failed"),
tr("Can't parse symbol usage file '%1'.")
.arg(filename));
tr("Can't parse symbol usage file '%1': %2")
.arg(filename)
.arg(error.errorString()));
}
mUsages.clear();

View File

@ -37,7 +37,7 @@ CodeCompletionPopup::CodeCompletionPopup(QWidget *parent) :
mOnlyGlobals = false;
mShowCount = 1000;
mShowCodeIns = true;
mShowCodeSnippets = true;
mIgnoreCase = false;
@ -469,9 +469,9 @@ void CodeCompletionPopup::getCompletionFor(const QString &fileName, const QStrin
int i = mParser->findLastOperator(phrase);
if (i < 0 ) { // don't have any scope prefix
if (mShowCodeIns) {
if (mShowCodeSnippets) {
//add custom code templates
foreach (const PCodeSnippet& codeIn,mCodeInsList) {
foreach (const PCodeSnippet& codeIn,mCodeSnippets) {
PStatement statement = std::make_shared<Statement>();
statement->command = codeIn->prefix;
statement->kind = StatementKind::skUserCodeIn;
@ -731,6 +731,16 @@ bool CodeCompletionPopup::isIncluded(const QString &fileName)
return mIncludedFiles.contains(fileName);
}
const QList<PCodeSnippet> &CodeCompletionPopup::codeSnippets() const
{
return mCodeSnippets;
}
void CodeCompletionPopup::setCodeSnippets(const QList<PCodeSnippet> &newCodeSnippets)
{
mCodeSnippets = newCodeSnippets;
}
void CodeCompletionPopup::setColors(const std::shared_ptr<QHash<StatementKind, QColor> > &newColors)
{
mColors = newColors;
@ -793,12 +803,12 @@ void CodeCompletionPopup::setIgnoreCase(bool newIgnoreCase)
bool CodeCompletionPopup::showCodeIns() const
{
return mShowCodeIns;
return mShowCodeSnippets;
}
void CodeCompletionPopup::setShowCodeIns(bool newShowCodeIns)
{
mShowCodeIns = newShowCodeIns;
mShowCodeSnippets = newShowCodeIns;
}
bool CodeCompletionPopup::showKeywords() const