From bc1b22ad251f84f087aff2b3a3df442702d22893 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 12 Jan 2023 12:07:22 +0800 Subject: [PATCH] - enhancement: Rename symbols won't remove all breakpoints/bookmarks - enhancement: Batch replace won't remove all breakpoints/bookmarks - enhancement: Execute parameters can be used in debug. --- NEWS.md | 3 + RedPandaIDE/compiler/compiler.h | 2 + RedPandaIDE/compiler/compilerinfo.h | 3 + RedPandaIDE/compiler/compilermanager.h | 2 + RedPandaIDE/compiler/executablerunner.h | 2 + RedPandaIDE/compiler/filecompiler.h | 3 +- RedPandaIDE/compiler/ojproblemcasesrunner.h | 2 + RedPandaIDE/compiler/projectcompiler.h | 2 + RedPandaIDE/compiler/runner.h | 2 + RedPandaIDE/compiler/stdincompiler.h | 2 + RedPandaIDE/cpprefacter.cpp | 133 +++++++++++--------- RedPandaIDE/debugger.cpp | 9 +- RedPandaIDE/debugger.h | 2 + RedPandaIDE/mainwindow.cpp | 18 ++- RedPandaIDE/parser/cppparser.h | 3 + RedPandaIDE/parser/cpppreprocessor.h | 3 + RedPandaIDE/parser/cpptokenizer.h | 2 + RedPandaIDE/parser/statementmodel.h | 2 + libs/qsynedit/qsynedit/document.h | 1 + libs/qsynedit/qsynedit/painter.h | 3 + libs/qsynedit/qsynedit/qsynedit.cpp | 32 +++++ libs/qsynedit/qsynedit/qsynedit.h | 3 + 22 files changed, 165 insertions(+), 69 deletions(-) diff --git a/NEWS.md b/NEWS.md index ff9fb9f9..1dca3dc9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -25,6 +25,9 @@ Red Panda C++ Version 2.8 - fix: Result of scope calculation not right if a for statement immediately follows another for statement. - fix: Function parameters that is pointer,reference or array can't be correctly parsed. - fix: In column mode, selection that contain lines with different length will cause error. + - enhancement: Rename symbols won't remove all breakpoints/bookmarks + - enhancement: Batch replace won't remove all breakpoints/bookmarks + - enhancement: Execute parameters can be used in debug. Red Panda C++ Version 2.7 diff --git a/RedPandaIDE/compiler/compiler.h b/RedPandaIDE/compiler/compiler.h index 68292354..7a194025 100644 --- a/RedPandaIDE/compiler/compiler.h +++ b/RedPandaIDE/compiler/compiler.h @@ -35,6 +35,8 @@ public: StdIn }; Compiler(const QString& filename, bool silent,bool onlyCheckSyntax); + Compiler(const Compiler&)=delete; + Compiler& operator=(const Compiler&)=delete; bool isRebuild() const; void setRebuild(bool isRebuild); diff --git a/RedPandaIDE/compiler/compilerinfo.h b/RedPandaIDE/compiler/compilerinfo.h index 0012495f..f4952bde 100644 --- a/RedPandaIDE/compiler/compilerinfo.h +++ b/RedPandaIDE/compiler/compilerinfo.h @@ -80,6 +80,9 @@ class CompilerInfo { public: CompilerInfo(const QString& name); + CompilerInfo(const CompilerInfo&)=delete; + CompilerInfo& operator=(const CompilerInfo&)=delete; + const QList &compilerOptions() const; const QString &name() const; PCompilerOption getCompilerOption(const QString& key) const; diff --git a/RedPandaIDE/compiler/compilermanager.h b/RedPandaIDE/compiler/compilermanager.h index 0cabaa32..85b8d04a 100644 --- a/RedPandaIDE/compiler/compilermanager.h +++ b/RedPandaIDE/compiler/compilermanager.h @@ -34,6 +34,8 @@ class CompilerManager : public QObject Q_OBJECT public: explicit CompilerManager(QObject *parent = nullptr); + CompilerManager(const CompilerManager&)=delete; + CompilerManager& operator=(const CompilerManager&)=delete; bool compiling(); bool backgroundSyntaxChecking(); diff --git a/RedPandaIDE/compiler/executablerunner.h b/RedPandaIDE/compiler/executablerunner.h index 65874580..8ccb9962 100644 --- a/RedPandaIDE/compiler/executablerunner.h +++ b/RedPandaIDE/compiler/executablerunner.h @@ -27,6 +27,8 @@ class ExecutableRunner : public Runner public: ExecutableRunner(const QString& filename, const QString& arguments, const QString& workDir, QObject* parent = nullptr); + ExecutableRunner(const ExecutableRunner&)=delete; + ExecutableRunner& operator=(const ExecutableRunner&)=delete; const QString &redirectInputFilename() const; void setRedirectInputFilename(const QString &newDataFile); diff --git a/RedPandaIDE/compiler/filecompiler.h b/RedPandaIDE/compiler/filecompiler.h index 4d9cf522..731a09bf 100644 --- a/RedPandaIDE/compiler/filecompiler.h +++ b/RedPandaIDE/compiler/filecompiler.h @@ -26,7 +26,8 @@ public: FileCompiler(const QString& filename, const QByteArray& encoding, CppCompileType compileType, bool silent,bool onlyCheckSyntax); - + FileCompiler(const FileCompiler&)=delete; + FileCompiler& operator=(const FileCompiler&)=delete; protected: bool prepareForCompile() override; diff --git a/RedPandaIDE/compiler/ojproblemcasesrunner.h b/RedPandaIDE/compiler/ojproblemcasesrunner.h index 5257899c..8fc03acd 100644 --- a/RedPandaIDE/compiler/ojproblemcasesrunner.h +++ b/RedPandaIDE/compiler/ojproblemcasesrunner.h @@ -31,6 +31,8 @@ public: explicit OJProblemCasesRunner(const QString& filename, const QString& arguments, const QString& workDir, POJProblemCase problemCase, QObject *parent = nullptr); + OJProblemCasesRunner(const OJProblemCasesRunner&)=delete; + OJProblemCasesRunner& operator=(const OJProblemCasesRunner&)=delete; //max size of output buffer int bufferSize() const; void setBufferSize(int newBufferSize); diff --git a/RedPandaIDE/compiler/projectcompiler.h b/RedPandaIDE/compiler/projectcompiler.h index 1a829c63..0ad76d07 100644 --- a/RedPandaIDE/compiler/projectcompiler.h +++ b/RedPandaIDE/compiler/projectcompiler.h @@ -27,6 +27,8 @@ class ProjectCompiler : public Compiler Q_OBJECT public: ProjectCompiler(std::shared_ptr project, bool silent,bool onlyCheckSyntax); + ProjectCompiler(const ProjectCompiler&)=delete; + ProjectCompiler& operator=(const ProjectCompiler&)=delete; void buildMakeFile(); bool onlyClean() const; diff --git a/RedPandaIDE/compiler/runner.h b/RedPandaIDE/compiler/runner.h index 9ef0b026..5de99eda 100644 --- a/RedPandaIDE/compiler/runner.h +++ b/RedPandaIDE/compiler/runner.h @@ -24,6 +24,8 @@ class Runner : public QThread Q_OBJECT public: explicit Runner(const QString& filename, const QString& arguments, const QString& workDir, QObject *parent = nullptr); + Runner(const Runner&)=delete; + Runner operator=(const Runner&)=delete; bool pausing() const; diff --git a/RedPandaIDE/compiler/stdincompiler.h b/RedPandaIDE/compiler/stdincompiler.h index e27cf68f..96860836 100644 --- a/RedPandaIDE/compiler/stdincompiler.h +++ b/RedPandaIDE/compiler/stdincompiler.h @@ -25,6 +25,8 @@ class StdinCompiler : public Compiler public: explicit StdinCompiler(const QString& filename, const QByteArray& encoding, const QString& content, bool silent,bool onlyCheckSyntax); + StdinCompiler(const StdinCompiler&)=delete; + StdinCompiler& operator=(const StdinCompiler&)=delete; protected: bool prepareForCompile() override; diff --git a/RedPandaIDE/cpprefacter.cpp b/RedPandaIDE/cpprefacter.cpp index a157f4f8..b67d6a4a 100644 --- a/RedPandaIDE/cpprefacter.cpp +++ b/RedPandaIDE/cpprefacter.cpp @@ -277,68 +277,89 @@ PSearchResultTreeItem CppRefacter::findOccurenceInFile( void CppRefacter::renameSymbolInFile(const QString &filename, const PStatement &statement, const QString &newWord, const PCppParser &parser) { QStringList buffer; - Editor editor(nullptr); - if (pMainWindow->editorList()->getContentFromOpenedEditor( - filename,buffer)){ - editor.document()->setContents(buffer); + Editor * oldEditor=pMainWindow->editorList()->getOpenedEditorByFilename(filename); + if (oldEditor){ + QSynedit::PSyntaxer syntaxer = syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP); + int posY = 0; + while (posY < oldEditor->document()->count()) { + QString line = oldEditor->document()->getLine(posY); + if (posY == 0) { + syntaxer->resetState(); + } else { + syntaxer->setState( + oldEditor->document()->getSyntaxState(posY-1)); + } + syntaxer->setLine(line,posY); + QString newLine; + while (!syntaxer->eol()) { + int start = syntaxer->getTokenPos() + 1; + QString token = syntaxer->getToken(); + if (token == statement->command) { + //same name symbol , test if the same statement; + QSynedit::BufferCoord p; + p.line = posY+1; + p.ch = start; + + QStringList expression = oldEditor->getExpressionAtPosition(p); + PStatement tokenStatement = parser->findStatementOf( + filename, + expression, p.line); + if (tokenStatement + && (tokenStatement->line == statement->line) + && (tokenStatement->fileName == statement->fileName)) { + token = newWord; + } + } + newLine += token; + syntaxer->next(); + } + if (newLine!=line) + oldEditor->replaceLine(posY+1,newLine); + posY++; + } } else { + Editor editor(nullptr); QByteArray encoding; editor.document()->loadFromFile(filename,ENCODING_AUTO_DETECT,encoding); - } - QStringList newContents; - editor.setSyntaxer(syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP)); - int posY = 0; - while (posY < editor.document()->count()) { - QString line = editor.document()->getLine(posY); + QStringList newContents; + editor.setSyntaxer(syntaxerManager.getSyntaxer(QSynedit::ProgrammingLanguage::CPP)); + int posY = 0; + while (posY < editor.document()->count()) { + QString line = editor.document()->getLine(posY); - if (posY == 0) { - editor.syntaxer()->resetState(); - } else { - editor.syntaxer()->setState( - editor.document()->getSyntaxState(posY-1)); - } - editor.syntaxer()->setLine(line,posY); - QString newLine; - while (!editor.syntaxer()->eol()) { - int start = editor.syntaxer()->getTokenPos() + 1; - QString token = editor.syntaxer()->getToken(); - if (token == statement->command) { - //same name symbol , test if the same statement; - QSynedit::BufferCoord p; - p.line = posY+1; - p.ch = start; - - QStringList expression = editor.getExpressionAtPosition(p); - PStatement tokenStatement = parser->findStatementOf( - filename, - expression, p.line); - if (tokenStatement - && (tokenStatement->line == statement->line) - && (tokenStatement->fileName == statement->fileName)) { - token = newWord; - } + if (posY == 0) { + editor.syntaxer()->resetState(); + } else { + editor.syntaxer()->setState( + editor.document()->getSyntaxState(posY-1)); } - newLine += token; - editor.syntaxer()->next(); - } - newContents.append(newLine); - posY++; - } + editor.syntaxer()->setLine(line,posY); + QString newLine; + while (!editor.syntaxer()->eol()) { + int start = editor.syntaxer()->getTokenPos() + 1; + QString token = editor.syntaxer()->getToken(); + if (token == statement->command) { + //same name symbol , test if the same statement; + QSynedit::BufferCoord p; + p.line = posY+1; + p.ch = start; - Editor * oldEditor = pMainWindow->editorList()->getOpenedEditorByFilename(filename); - if (oldEditor) { - QSynedit::BufferCoord oldXY=oldEditor->caretXY(); - int topLine = oldEditor->topLine(); - int leftChar = oldEditor->leftChar(); - oldEditor->beginUndoBlock(); - oldEditor->addLeftTopToUndo(); - oldEditor->addCaretToUndo(); - oldEditor->replaceAll(newContents.join(oldEditor->lineBreak())); - oldEditor->setTopLine(topLine); - oldEditor->setLeftChar(leftChar); - oldEditor->setCaretXY(oldXY); - oldEditor->endUndoBlock(); - } else { + QStringList expression = editor.getExpressionAtPosition(p); + PStatement tokenStatement = parser->findStatementOf( + filename, + expression, p.line); + if (tokenStatement + && (tokenStatement->line == statement->line) + && (tokenStatement->fileName == statement->fileName)) { + token = newWord; + } + } + newLine += token; + editor.syntaxer()->next(); + } + newContents.append(newLine); + posY++; + } QByteArray realEncoding; QFile file(filename); editor.document()->saveToFile(file,ENCODING_AUTO_DETECT, diff --git a/RedPandaIDE/debugger.cpp b/RedPandaIDE/debugger.cpp index 0143ab13..8c8028e7 100644 --- a/RedPandaIDE/debugger.cpp +++ b/RedPandaIDE/debugger.cpp @@ -130,7 +130,10 @@ bool Debugger::start(int compilerSetIndex, const QString& inferior, const QStrin mWatchModel->resetAllVarInfos(); if (pSettings->debugger().useGDBServer()) { //deleted when thread finished - mTarget = new DebugTarget(inferior,compilerSet->debugServer(),pSettings->debugger().GDBServerPort()); + QString params; + if (pSettings->executor().useParams()) + params = pSettings->executor().params(); + mTarget = new DebugTarget(inferior,compilerSet->debugServer(),pSettings->debugger().GDBServerPort(),params); if (pSettings->executor().redirectInput()) mTarget->setInputFile(pSettings->executor().inputFilename()); connect(mTarget, &QThread::finished,[this](){ @@ -2668,9 +2671,11 @@ DebugTarget::DebugTarget( const QString &inferior, const QString &GDBServer, int port, + const QString& arguments, QObject *parent): QThread(parent), mInferior(inferior), + mArguments(arguments), mGDBServer(GDBServer), mPort(port), mStop(false), @@ -2720,7 +2725,7 @@ void DebugTarget::run() QString arguments; #ifdef Q_OS_WIN cmd= mGDBServer; - arguments = QString(" localhost:%1 \"%2\"").arg(mPort).arg(mInferior); + arguments = QString(" localhost:%1 \"%2\" %3").arg(mPort).arg(mInferior,mArguments); #else cmd= pSettings->environment().terminalPath(); arguments = QString(" -e \"%1\" localhost:%2 \"%3\"").arg(mGDBServer).arg(mPort).arg(mInferior); diff --git a/RedPandaIDE/debugger.h b/RedPandaIDE/debugger.h index eabbed09..6463703d 100644 --- a/RedPandaIDE/debugger.h +++ b/RedPandaIDE/debugger.h @@ -413,6 +413,7 @@ public: explicit DebugTarget(const QString& inferior, const QString& GDBServer, int port, + const QString& arguments, QObject *parent = nullptr); void setInputFile(const QString& inputFile); void stopDebug(); @@ -424,6 +425,7 @@ signals: void processError(QProcess::ProcessError error); private: QString mInferior; + QString mArguments; QString mGDBServer; int mPort; bool mStop; diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index f8b4fb08..a9e49ec7 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -2315,11 +2315,17 @@ void MainWindow::debug() if (!debugInferiorhasBreakpoint()) { mDebugger->sendCommand("-break-insert","-t main"); } + if (pSettings->executor().useParams()) { + mDebugger->sendCommand("-exec-arguments", pSettings->executor().params()); + } mDebugger->sendCommand("-exec-continue",""); } else { #ifdef Q_OS_WIN mDebugger->sendCommand("-gdb-set", "new-console on"); #endif + if (pSettings->executor().useParams()) { + mDebugger->sendCommand("-exec-arguments", pSettings->executor().params()); + } if (!debugInferiorhasBreakpoint()) { mDebugger->sendCommand("-exec-run", "--start"); } else { @@ -7707,12 +7713,11 @@ void MainWindow::on_btnReplace_clicked() tr("Can't open file '%1' for replace!").arg(file->filename)); return; } - contents = editor->contents(); for (int i=file->results.count()-1;i>=0;i--) { const PSearchResultTreeItem& item = file->results[i]; if (!item->selected) continue; - QString line = contents[item->line-1]; + QString line = editor->document()->getLine(item->line-1); if (line.mid(item->start-1,results->keyword.length())!=results->keyword) { QMessageBox::critical(editor, tr("Replace Error"), @@ -7721,15 +7726,8 @@ void MainWindow::on_btnReplace_clicked() } line.remove(item->start-1,results->keyword.length()); line.insert(item->start-1, newWord); - contents[item->line-1] = line; + editor->replaceLine(item->line,line); } - QSynedit::BufferCoord coord=editor->caretXY(); - int topLine = editor->topLine(); - int leftChar = editor->leftChar(); - editor->replaceAll(contents.join(editor->lineBreak())); - editor->setCaretXY(coord); - editor->setTopLine(topLine); - editor->setLeftChar(leftChar); } showSearchReplacePanel(false); stretchMessagesPanel(false); diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 63c7d49a..089076a4 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -31,6 +31,9 @@ class CppParser : public QObject public: explicit CppParser(QObject *parent = nullptr); + CppParser(const CppParser&)=delete; + CppParser& operator=(const CppParser)=delete; + ~CppParser(); void addHardDefineByLine(const QString& line); diff --git a/RedPandaIDE/parser/cpppreprocessor.h b/RedPandaIDE/parser/cpppreprocessor.h index da039c6b..0dccbecb 100644 --- a/RedPandaIDE/parser/cpppreprocessor.h +++ b/RedPandaIDE/parser/cpppreprocessor.h @@ -61,6 +61,9 @@ class CppPreprocessor public: explicit CppPreprocessor(); + CppPreprocessor(const CppPreprocessor&)=delete; + CppPreprocessor& operator=(const CppPreprocessor&)=delete; + void clear(); void clearTempResults(); diff --git a/RedPandaIDE/parser/cpptokenizer.h b/RedPandaIDE/parser/cpptokenizer.h index 0188e5f1..85265b17 100644 --- a/RedPandaIDE/parser/cpptokenizer.h +++ b/RedPandaIDE/parser/cpptokenizer.h @@ -43,6 +43,8 @@ public: using PToken = std::shared_ptr; using TokenList = QVector; explicit CppTokenizer(); + CppTokenizer(const CppTokenizer&)=delete; + CppTokenizer& operator=(const CppTokenizer&)=delete; void clear(); void tokenize(const QStringList& buffer); diff --git a/RedPandaIDE/parser/statementmodel.h b/RedPandaIDE/parser/statementmodel.h index 96c9f68a..48bca5c1 100644 --- a/RedPandaIDE/parser/statementmodel.h +++ b/RedPandaIDE/parser/statementmodel.h @@ -26,6 +26,8 @@ class StatementModel : public QObject Q_OBJECT public: explicit StatementModel(QObject *parent = nullptr); + StatementModel(const StatementModel&)=delete; + StatementModel& operator=(const StatementModel&)=delete; void add(const PStatement& statement); // function DeleteFirst: Integer; diff --git a/libs/qsynedit/qsynedit/document.h b/libs/qsynedit/qsynedit/document.h index 32ef9719..f5482892 100644 --- a/libs/qsynedit/qsynedit/document.h +++ b/libs/qsynedit/qsynedit/document.h @@ -169,6 +169,7 @@ enum class ChangeReason { LineBreak, MoveSelectionUp, MoveSelectionDown, + ReplaceLine, Nothing // undo list empty }; diff --git a/libs/qsynedit/qsynedit/painter.h b/libs/qsynedit/qsynedit/painter.h index b82aff06..dcc8b628 100644 --- a/libs/qsynedit/qsynedit/painter.h +++ b/libs/qsynedit/qsynedit/painter.h @@ -41,6 +41,9 @@ class QSynEditPainter public: QSynEditPainter(QSynEdit * edit,QPainter* painter,int FirstRow, int LastRow, int FirstCol, int LastCol); + QSynEditPainter(const QSynEditPainter&)=delete; + QSynEditPainter& operator=(const QSynEditPainter&)=delete; + void paintTextLines(const QRect& clip); void paintGutter(const QRect& clip); diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index f92f06d5..8b10949b 100644 --- a/libs/qsynedit/qsynedit/qsynedit.cpp +++ b/libs/qsynedit/qsynedit/qsynedit.cpp @@ -4367,6 +4367,18 @@ void QSynEdit::doUndoItem() ensureCursorPosVisible(); break; } + case ChangeReason::ReplaceLine: + qDebug()<changeStartPos().line<changeText(); + mRedoList->addRedo( + item->changeReason(), + item->changeStartPos(), + item->changeEndPos(), + QStringList(mDocument->getLine(item->changeStartPos().line-1)), + item->changeSelMode(), + item->changeNumber() + ); + mDocument->putLine(item->changeStartPos().line-1,item->changeText()[0]); + break; case ChangeReason::MoveSelectionUp: setBlockBegin(BufferCoord{item->changeStartPos().ch, item->changeStartPos().line-1}); setBlockEnd(BufferCoord{item->changeEndPos().ch, item->changeEndPos().line-1}); @@ -4564,6 +4576,17 @@ void QSynEdit::doRedoItem() item->changeSelMode(), item->changeNumber()); break; + case ChangeReason::ReplaceLine: + mUndoList->restoreChange( + item->changeReason(), + item->changeStartPos(), + item->changeEndPos(), + QStringList(mDocument->getLine(item->changeStartPos().line-1)), + item->changeSelMode(), + item->changeNumber() + ); + mDocument->putLine(item->changeStartPos().line-1,item->changeText()[0]); + break; case ChangeReason::Insert: setCaretAndSelection( item->changeStartPos(), @@ -6850,6 +6873,15 @@ void QSynEdit::setSelText(const QString &text) doSetSelText(text); } +void QSynEdit::replaceLine(int line, const QString &lineText) +{ + BufferCoord pos; + pos.line=line; + pos.ch=1; + mUndoList->addChange(ChangeReason::ReplaceLine,pos,pos,QStringList(mDocument->getLine(line-1)),SelectionMode::Normal); + mDocument->putLine(line-1,lineText); +} + BufferCoord QSynEdit::blockBegin() const { if (mActiveSelectionMode==SelectionMode::Column) diff --git a/libs/qsynedit/qsynedit/qsynedit.h b/libs/qsynedit/qsynedit/qsynedit.h index e822f610..5eb37c3d 100644 --- a/libs/qsynedit/qsynedit/qsynedit.h +++ b/libs/qsynedit/qsynedit/qsynedit.h @@ -138,6 +138,8 @@ class QSynEdit : public QAbstractScrollArea Q_OBJECT public: explicit QSynEdit(QWidget* parent=nullptr); + QSynEdit(const QSynEdit&)=delete; + QSynEdit& operator=(const QSynEdit&)=delete; /** * Returns how many rows are there in the editor * @return @@ -232,6 +234,7 @@ public: void setSelLength(int Value); void setSelText(const QString& text); + void replaceLine(int line, const QString& lineText); int searchReplace(const QString& sSearch, const QString& sReplace, SearchOptions options, PSynSearchBase searchEngine, SearchMathedProc matchedCallback = nullptr, SearchConfirmAroundProc confirmAroundCallback = nullptr);