From d629a496ff5c2b3db85ee1cd68dcc11149f0bd94 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Wed, 12 Jul 2023 12:08:26 +0800 Subject: [PATCH] - fix: Shouldn't auto indent lines starts with "\\". - enhancement: When problem case's expected output is not too large (<= 5000 line), highlight text in the first different line in the expected output. - enhancement: Highlight text in the first different line using the error color. - enhancement: Add the option "redirect stderr to the Tools output panel" in the options dialog -> executor -> problem set page. --- NEWS.md | 4 + RedPandaIDE/compiler/compilermanager.cpp | 3 + RedPandaIDE/compiler/ojproblemcasesrunner.cpp | 17 +- RedPandaIDE/compiler/ojproblemcasesrunner.h | 1 + RedPandaIDE/mainwindow.cpp | 68 +++- RedPandaIDE/problems/problemcasevalidator.cpp | 21 +- RedPandaIDE/settings.cpp | 13 + RedPandaIDE/settings.h | 4 + .../executorproblemsetwidget.cpp | 2 + .../executorproblemsetwidget.ui | 7 + RedPandaIDE/translations/RedPandaIDE_pt_BR.ts | 4 + RedPandaIDE/translations/RedPandaIDE_zh_CN.ts | 359 +++++++++--------- RedPandaIDE/translations/RedPandaIDE_zh_TW.ts | 4 + RedPandaIDE/widgets/linenumbertexteditor.cpp | 21 + RedPandaIDE/widgets/linenumbertexteditor.h | 6 + libs/qsynedit/qsynedit/qsynedit.cpp | 2 + libs/qsynedit/qsynedit_zh_CN.ts | 11 +- libs/redpanda_qt_utils/qt_utils/utils.cpp | 9 + libs/redpanda_qt_utils/qt_utils/utils.h | 3 + libs/redpanda_qt_utils/qt_utils_zh_CN.ts | 2 +- 20 files changed, 359 insertions(+), 202 deletions(-) diff --git a/NEWS.md b/NEWS.md index 09499b80..5e55592f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -38,6 +38,10 @@ Red Panda C++ Version 2.23 - enhancement: Auto insert spaces between #include and "" when reformat - fix: Click editor's gutter won't toggle breakpoint in KDE debian 12 - fix: "Toggle breakpoint " in the editor gutter's context menu doesn't work. + - fix: Shouldn't auto indent lines starts with "\\". + - enhancement: When problem case's expected output is not too large (<= 5000 line), highlight text in the first different line in the expected output. + - enhancement: Highlight text in the first different line using the error color. + - enhancement: Add the option "redirect stderr to the Tools output panel" in the options dialog -> executor -> problem set page. Red Panda C++ Version 2.22 diff --git a/RedPandaIDE/compiler/compilermanager.cpp b/RedPandaIDE/compiler/compilermanager.cpp index 450de3e8..7914a008 100644 --- a/RedPandaIDE/compiler/compilermanager.cpp +++ b/RedPandaIDE/compiler/compilermanager.cpp @@ -357,6 +357,9 @@ void CompilerManager::doRunProblem(const QString &filename, const QString &argum connect(execRunner, &OJProblemCasesRunner::caseFinished, pMainWindow, &MainWindow::onOJProblemCaseFinished); connect(execRunner, &OJProblemCasesRunner::newOutputGetted, pMainWindow, &MainWindow::onOJProblemCaseNewOutputGetted); connect(execRunner, &OJProblemCasesRunner::resetOutput, pMainWindow, &MainWindow::onOJProblemCaseResetOutput); + if (pSettings->executor().redirectStderrToToolLog()) { + connect(execRunner, &OJProblemCasesRunner::logStderrOutput, pMainWindow, &MainWindow::logToolsOutput); + } mRunner->start(); } diff --git a/RedPandaIDE/compiler/ojproblemcasesrunner.cpp b/RedPandaIDE/compiler/ojproblemcasesrunner.cpp index 65d4c071..40a72e08 100644 --- a/RedPandaIDE/compiler/ojproblemcasesrunner.cpp +++ b/RedPandaIDE/compiler/ojproblemcasesrunner.cpp @@ -83,7 +83,12 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase) } env.insert("PATH",path); process.setProcessEnvironment(env); - process.setProcessChannelMode(QProcess::MergedChannels); + if (pSettings->executor().redirectStderrToToolLog()) { + emit logStderrOutput("\n"); + } else { + process.setProcessChannelMode(QProcess::MergedChannels); + process.setReadChannel(QProcess::StandardOutput); + } process.connect( &process, &QProcess::errorOccurred, [&](){ @@ -129,6 +134,11 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase) } if (errorOccurred) break; + if (pSettings->executor().redirectStderrToToolLog()) { + QString s = QString::fromLocal8Bit(process.readAllStandardError()); + if (!s.isEmpty()) + emit logStderrOutput(s); + } readed = process.read(mBufferSize); buffer += readed; if (buffer.length()>=mBufferSize || noOutputTime > mOutputRefreshTime) { @@ -171,6 +181,11 @@ void OJProblemCasesRunner::runCase(int index,POJProblemCase problemCase) problemCase->output = tr("Memory limit exceeded!"); emit resetOutput(problemCase->getId(), problemCase->output); } else { + if (pSettings->executor().redirectStderrToToolLog()) { + QString s = QString::fromLocal8Bit(process.readAllStandardError()); + if (!s.isEmpty()) + emit logStderrOutput(s); + } if (process.state() == QProcess::ProcessState::NotRunning) buffer += process.readAll(); emit newOutputGetted(problemCase->getId(),QString::fromLocal8Bit(buffer)); diff --git a/RedPandaIDE/compiler/ojproblemcasesrunner.h b/RedPandaIDE/compiler/ojproblemcasesrunner.h index 8fc03acd..6162899d 100644 --- a/RedPandaIDE/compiler/ojproblemcasesrunner.h +++ b/RedPandaIDE/compiler/ojproblemcasesrunner.h @@ -54,6 +54,7 @@ signals: void caseFinished(const QString &caseId, int current, int total); void newOutputGetted(const QString &caseId, const QString &newOutputLine); void resetOutput(const QString &caseId, const QString &newOutputLine); + void logStderrOutput(const QString& msg); private: void runCase(int index, POJProblemCase problemCase); private: diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index aa6ed124..914a7103 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -4044,9 +4044,9 @@ void MainWindow::onProblemSetIndexChanged(const QModelIndex ¤t, const QMod if (!idx.isValid()) { mProblemSet_RemoveProblem->setEnabled(false); mOJProblemModel.setProblem(nullptr); - ui->txtProblemCaseExpected->clear(); - ui->txtProblemCaseInput->clear(); - ui->txtProblemCaseOutput->clear(); + ui->txtProblemCaseExpected->clearAll(); + ui->txtProblemCaseInput->clearAll(); + ui->txtProblemCaseOutput->clearAll(); ui->tabProblem->setEnabled(false); ui->lblProblem->clear(); ui->lblProblem->setToolTip(""); @@ -4087,7 +4087,7 @@ void MainWindow::onProblemCaseIndexChanged(const QModelIndex ¤t, const QMo mProblem_RemoveCases->setEnabled(true); mProblem_RunAllCases->setEnabled(ui->actionRun->isEnabled()); fillProblemCaseInputAndExpected(problemCase); - ui->txtProblemCaseOutput->clear(); + ui->txtProblemCaseOutput->clearAll(); ui->txtProblemCaseOutput->setPlainText(problemCase->output); updateProblemCaseOutput(problemCase); return; @@ -4107,11 +4107,11 @@ void MainWindow::onProblemCaseIndexChanged(const QModelIndex ¤t, const QMo mProblem_RunAllCases->setEnabled(false); ui->txtProblemCaseInputFileName->clear(); ui->btnProblemCaseInputFileName->setEnabled(false); - ui->txtProblemCaseInput->clear(); + ui->txtProblemCaseInput->clearAll(); ui->txtProblemCaseInput->setReadOnly(true); - ui->txtProblemCaseExpected->clear(); + ui->txtProblemCaseExpected->clearAll(); ui->txtProblemCaseExpected->setReadOnly(true); - ui->txtProblemCaseOutput->clear(); + ui->txtProblemCaseOutput->clearAll(); ui->lblProblemCaseExpected->clear(); ui->lblProblemCaseOutput->clear(); @@ -5961,7 +5961,10 @@ void MainWindow::onOJProblemCaseStarted(const QString& id,int current, int total if (!idx.isValid() || row != idx.row()) { ui->tblProblemCases->setCurrentIndex(mOJProblemModel.index(row,0)); } - ui->txtProblemCaseOutput->clear(); + ui->txtProblemCaseOutput->clearAll(); + if (ui->txtProblemCaseExpected->document()->blockCount()<=5000) { + ui->txtProblemCaseExpected->clearFormat(); + } } } @@ -5989,6 +5992,7 @@ void MainWindow::onOJProblemCaseNewOutputGetted(const QString &/* id */, const Q void MainWindow::onOJProblemCaseResetOutput(const QString &/* id */, const QString &line) { + ui->txtProblemCaseOutput->clearAll(); ui->txtProblemCaseOutput->setPlainText(line); } @@ -7439,12 +7443,14 @@ void MainWindow::fillProblemCaseInputAndExpected(const POJProblemCase &problemCa ui->btnProblemCaseExpectedOutputFileName->setEnabled(true); if (fileExists(problemCase->expectedOutputFileName)) { ui->txtProblemCaseExpected->setReadOnly(true); + ui->txtProblemCaseExpected->clearAll(); ui->txtProblemCaseExpected->setPlainText(readFileToByteArray(problemCase->expectedOutputFileName)); ui->btnProblemCaseClearExpectedOutputFileName->setVisible(true); ui->txtProblemCaseExpectedOutputFileName->setText(extractFileName(problemCase->expectedOutputFileName)); ui->txtProblemCaseExpectedOutputFileName->setToolTip(problemCase->inputFileName); } else { ui->txtProblemCaseExpected->setReadOnly(false); + ui->txtProblemCaseExpected->clearAll(); ui->txtProblemCaseExpected->setPlainText(problemCase->expected); ui->btnProblemCaseClearExpectedOutputFileName->setVisible(false); ui->txtProblemCaseExpectedOutputFileName->clear(); @@ -8003,14 +8009,11 @@ void MainWindow::doGenerateAssembly() void MainWindow::updateProblemCaseOutput(POJProblemCase problemCase) { if (problemCase->testState == ProblemCaseTestState::Failed) { - int diffLine; - if (problemCase->outputLineCounts > problemCase->expectedLineCounts) { - diffLine = problemCase->expectedLineCounts; - } else if (problemCase->outputLineCounts < problemCase->expectedLineCounts) { - diffLine = problemCase->outputLineCounts; - } else { + int diffLine=-1; + if (problemCase->firstDiffLine!=-1) { diffLine = problemCase->firstDiffLine; - } + } else + return; if (diffLine < problemCase->outputLineCounts) { QTextBlock block = ui->txtProblemCaseOutput->document()->findBlockByLineNumber(diffLine); if (!block.isValid()) @@ -8020,17 +8023,48 @@ void MainWindow::updateProblemCaseOutput(POJProblemCase problemCase) return; cur = QTextCursor(block); QTextCharFormat oldFormat = cur.charFormat(); - QTextCharFormat format = cur.charFormat(); + QTextCharFormat format = QTextCharFormat(cur.charFormat()); cur.select(QTextCursor::LineUnderCursor); format.setUnderlineColor(mErrorColor); format.setUnderlineStyle(QTextCharFormat::WaveUnderline); + format.setTextOutline(mErrorColor); cur.setCharFormat(format); cur.clearSelection(); cur.setCharFormat(oldFormat); ui->txtProblemCaseOutput->setTextCursor(cur); - } else if (diffLine < problemCase->expectedLineCounts) { + ui->txtProblemCaseOutput->moveCursor(QTextCursor::MoveOperation::StartOfLine); + } else { ui->txtProblemCaseOutput->moveCursor(QTextCursor::MoveOperation::End); + ui->txtProblemCaseOutput->moveCursor(QTextCursor::MoveOperation::StartOfLine); } + if (diffLine < problemCase->expectedLineCounts) { + QTextBlock block = ui->txtProblemCaseExpected->document()->findBlockByLineNumber(diffLine); + if (!block.isValid()) + return; + QTextCursor cur(block); + if (cur.isNull()) + return; + cur = QTextCursor(block); + if (ui->txtProblemCaseExpected->document()->blockCount()<=5000) { + QTextCharFormat oldFormat = cur.charFormat(); + QTextCharFormat format = QTextCharFormat(cur.charFormat()); + cur.select(QTextCursor::LineUnderCursor); + format.setUnderlineColor(mErrorColor); + format.setUnderlineStyle(QTextCharFormat::WaveUnderline); + format.setTextOutline(mErrorColor); + cur.setCharFormat(format); + cur.clearSelection(); + cur.setCharFormat(oldFormat); + } + ui->txtProblemCaseExpected->setTextCursor(cur); + ui->txtProblemCaseExpected->moveCursor(QTextCursor::MoveOperation::StartOfLine); + } else { + ui->txtProblemCaseExpected->moveCursor(QTextCursor::MoveOperation::End); + ui->txtProblemCaseExpected->moveCursor(QTextCursor::MoveOperation::StartOfLine); + } + } else { + ui->txtProblemCaseOutput->moveCursor(QTextCursor::MoveOperation::Start); + ui->txtProblemCaseExpected->moveCursor(QTextCursor::MoveOperation::Start); } } diff --git a/RedPandaIDE/problems/problemcasevalidator.cpp b/RedPandaIDE/problems/problemcasevalidator.cpp index aaef0fe5..5fddfb85 100644 --- a/RedPandaIDE/problems/problemcasevalidator.cpp +++ b/RedPandaIDE/problems/problemcasevalidator.cpp @@ -34,9 +34,17 @@ bool ProblemCaseValidator::validate(POJProblemCase problemCase, bool ignoreSpace expected = textToLines(problemCase->expected); problemCase->outputLineCounts = output.count(); problemCase->expectedLineCounts = expected.count(); - if (output.count()!=expected.count()) - return false; - for (int i=0;iexpectedLineCounts>5000) { + if (output.count()firstDiffLine=output.count(); + return false; + } else if (output.count()>expected.count()) { + problemCase->firstDiffLine=expected.count(); + return false; + } + } + int count=std::min(output.count(), expected.count()); + for (int i=0;ifirstDiffLine = i; @@ -49,6 +57,13 @@ bool ProblemCaseValidator::validate(POJProblemCase problemCase, bool ignoreSpace } } } + if (output.count()firstDiffLine=output.count(); + return false; + } else if (output.count()>expected.count()) { + problemCase->firstDiffLine=expected.count(); + return false; + } return true; } diff --git a/RedPandaIDE/settings.cpp b/RedPandaIDE/settings.cpp index 3551182d..072db153 100644 --- a/RedPandaIDE/settings.cpp +++ b/RedPandaIDE/settings.cpp @@ -3719,6 +3719,16 @@ void Settings::Executor::setConvertHTMLToTextForExpected(bool newConvertHTMLToTe mConvertHTMLToTextForExpected = newConvertHTMLToTextForExpected; } +bool Settings::Executor::redirectStderrToToolLog() const +{ + return mRedirectStderrToToolLog; +} + +void Settings::Executor::setRedirectStderrToToolLog(bool newRedirectStderrToToolLog) +{ + mRedirectStderrToToolLog = newRedirectStderrToToolLog; +} + bool Settings::Executor::convertHTMLToTextForInput() const { return mConvertHTMLToTextForInput; @@ -3794,6 +3804,7 @@ void Settings::Executor::doSave() saveValue("input_convert_html", mConvertHTMLToTextForInput); saveValue("expected_convert_html", mConvertHTMLToTextForExpected); saveValue("ignore_spaces_when_validating_cases", mIgnoreSpacesWhenValidatingCases); + saveValue("redirect_stderr_to_toollog", mRedirectStderrToToolLog); saveValue("case_editor_font_name",mCaseEditorFontName); saveValue("case_editor_font_size",mCaseEditorFontSize); saveValue("case_editor_font_only_monospaced",mCaseEditorFontOnlyMonospaced); @@ -3828,6 +3839,8 @@ void Settings::Executor::doLoad() mConvertHTMLToTextForInput = boolValue("input_convert_html", false); mConvertHTMLToTextForExpected = boolValue("expected_convert_html", false); mIgnoreSpacesWhenValidatingCases = boolValue("ignore_spaces_when_validating_cases",false); + mRedirectStderrToToolLog = boolValue("redirect_stderr_to_toollog", false); + #ifdef Q_OS_WIN mCaseEditorFontName = stringValue("case_editor_font_name","consolas"); #elif defined(Q_OS_MACOS) diff --git a/RedPandaIDE/settings.h b/RedPandaIDE/settings.h index a803a2a2..60f8ef95 100644 --- a/RedPandaIDE/settings.h +++ b/RedPandaIDE/settings.h @@ -931,6 +931,9 @@ public: bool convertHTMLToTextForExpected() const; void setConvertHTMLToTextForExpected(bool newConvertHTMLToTextForExpected); + bool redirectStderrToToolLog() const; + void setRedirectStderrToToolLog(bool newRedirectStderrToToolLog); + private: // general bool mPauseConsole; @@ -947,6 +950,7 @@ public: bool mConvertHTMLToTextForInput; bool mConvertHTMLToTextForExpected; bool mIgnoreSpacesWhenValidatingCases; + bool mRedirectStderrToToolLog; QString mCaseEditorFontName; int mCaseEditorFontSize; bool mCaseEditorFontOnlyMonospaced; diff --git a/RedPandaIDE/settingsdialog/executorproblemsetwidget.cpp b/RedPandaIDE/settingsdialog/executorproblemsetwidget.cpp index cbd4f909..9dff813d 100644 --- a/RedPandaIDE/settingsdialog/executorproblemsetwidget.cpp +++ b/RedPandaIDE/settingsdialog/executorproblemsetwidget.cpp @@ -40,6 +40,7 @@ void ExecutorProblemSetWidget::doLoad() ui->chkConvertExpectedHTML->setChecked(pSettings->executor().convertHTMLToTextForExpected()); ui->chkIgnoreSpacesWhenValidatingCases->setChecked(pSettings->executor().ignoreSpacesWhenValidatingCases()); + ui->chkRedirectStderr->setChecked(pSettings->executor().redirectStderrToToolLog()); ui->cbFont->setCurrentFont(QFont(pSettings->executor().caseEditorFontName())); ui->spinFontSize->setValue(pSettings->executor().caseEditorFontSize()); @@ -58,6 +59,7 @@ void ExecutorProblemSetWidget::doSave() pSettings->executor().setConvertHTMLToTextForInput(ui->chkConvertInputHTML->isChecked()); pSettings->executor().setConvertHTMLToTextForExpected(ui->chkConvertExpectedHTML->isChecked()); pSettings->executor().setIgnoreSpacesWhenValidatingCases(ui->chkIgnoreSpacesWhenValidatingCases->isChecked()); + pSettings->executor().setRedirectStderrToToolLog(ui->chkRedirectStderr->isChecked()); pSettings->executor().setCaseEditorFontName(ui->cbFont->currentFont().family()); pSettings->executor().setCaseEditorFontOnlyMonospaced(ui->chkOnlyMonospaced->isChecked()); pSettings->executor().setCaseEditorFontSize(ui->spinFontSize->value()); diff --git a/RedPandaIDE/settingsdialog/executorproblemsetwidget.ui b/RedPandaIDE/settingsdialog/executorproblemsetwidget.ui index a3c3a938..b8b3134b 100644 --- a/RedPandaIDE/settingsdialog/executorproblemsetwidget.ui +++ b/RedPandaIDE/settingsdialog/executorproblemsetwidget.ui @@ -117,6 +117,13 @@ + + + + Redirect STDERR to Tools output panel + + + diff --git a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts index 1b2d139c..58c74d3b 100644 --- a/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts +++ b/RedPandaIDE/translations/RedPandaIDE_pt_BR.ts @@ -2105,6 +2105,10 @@ Expected Output + + Redirect STDERR to Tools output panel + + FileAssociationModel diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts index 3426bed8..609d11d9 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_CN.ts @@ -2838,26 +2838,31 @@ Are you really want to continue? + Redirect STDERR to Tools output panel + 将标准输出内容重定向到工具输出面板 + + + Ignore spaces when validating problem cases 在验证测试案例时忽略结果中的空格 - + Case Valdation Limit 测试案例验证的资源限制 - + Time Limit 时间限制 - + Memory Limit 内存限制 - + kb kb @@ -2866,7 +2871,7 @@ Are you really want to continue? 试题案例超时时间 - + ms 毫秒 @@ -2875,22 +2880,22 @@ Are you really want to continue? - + Case Editor Font 试题案例数据编辑字体 - + Font Size: 大小: - + Font: 字体: - + Only Monospaced 仅使用等宽字体 @@ -4339,7 +4344,7 @@ Are you really want to continue? - + Issues 编译器 @@ -4772,7 +4777,7 @@ Are you really want to continue? - + New Problem Set 新建试题集 @@ -4794,7 +4799,7 @@ Are you really want to continue? - + Save Problem Set 保存试题集 @@ -4802,7 +4807,7 @@ Are you really want to continue? - + Load Problem Set 载入试题集 @@ -4933,14 +4938,14 @@ Are you really want to continue? - + Import FPS Problem Set 导入FPS试题集 - + Export FPS Problem Set 导出FPS试题集 @@ -5192,7 +5197,7 @@ Are you really want to continue? - + Clear all breakpoints 删除所有断点 @@ -5597,7 +5602,7 @@ Are you really want to continue? - + Rename Symbol 重命名符号 @@ -5618,13 +5623,13 @@ Are you really want to continue? - + Export As RTF 导出为RTF - + Export As HTML 导出为HTML @@ -6182,22 +6187,22 @@ Are you really want to continue? 全部复制 - + Go to Line 跳转到行 - + Line - + Template Exists 模板已存在 - + Template %1 already exists. Do you want to overwrite? 模板%1已存在。是否覆盖? @@ -6223,7 +6228,7 @@ Are you really want to continue? - + Problem Set %1 试题集%1 @@ -6293,15 +6298,15 @@ Are you really want to continue? - - + + Bookmark Description 书签描述 - - + + Description: 描述: @@ -6523,7 +6528,7 @@ Are you really want to continue? - + Delete 删除 @@ -6618,12 +6623,12 @@ Are you really want to continue? 保存设置失败 - + Watchpoint variable name 被监控的变量 - + Stop execution when the following variable is modified (it must be visible from the currect scope): 当下面的变量被修改时暂停执行(该变量必须可以从当前程序处访问): @@ -6632,17 +6637,17 @@ Are you really want to continue? 中止 - + FPS Problem Set Files (*.fps;*.xml) FPS试题集文件(*.fps;*.xml) - + FPS Problem Set Files (*.fps) FPS试题集文件(*.fps) - + Export Error 导出时出错 @@ -6704,7 +6709,7 @@ Are you really want to continue? - + Do you want to save it? 需要保存吗? @@ -6716,15 +6721,15 @@ Are you really want to continue? - - + + New Project File? 新建项目文件? - - + + Do you want to add the new file to the project? 您是否要将新建的文件加入项目? @@ -6733,7 +6738,7 @@ Are you really want to continue? - + Save Error 保存失败 @@ -6775,78 +6780,78 @@ Are you really want to continue? 无标题%1 - + Modify Watch 修改监视表达式 - + Watch Expression 监视表达式 - + Do you really want to clear all breakpoints in this file? 您真的要清除该文件的所有断点吗? - + New project 新建项目 - + Close %1 and start new project? 关闭'%1'以打开新项目? - + Folder not exist 文件夹不存在 - + Folder '%1' doesn't exist. Create it now? 文件夹'%1'不存在。是否创建? - + Can't create folder 无法创建文件夹 - + Failed to create folder '%1'. 创建文件夹'%1'失败。 - + Save new project as - + Folder %1 is not empty. 文件夹%1不是空的。 - + Do you really want to delete it? 你真的要删除它吗? - + Change working folder 改变工作文件夹 - + File '%1' is not in the current working folder. File '%1' is not in the current working folder 文件'%1'不在当前工作文件夹中。 - + Do you want to change working folder to '%1'? 是否将工作文件夹改设为'%1'? @@ -6855,28 +6860,28 @@ Are you really want to continue? 正在删除试题... - + Can't Commit 无法提交 - + Git needs user info to commit. Git需要用信息进行提交。 - + Choose Input Data File 选择输入数据文件 - - + + All files (*.*) 所有文件 (*.*) - + Choose Expected Output Data File Choose Expected Input Data File 选择期望输出文件 @@ -6888,59 +6893,59 @@ Are you really want to continue? - + Choose Working Folder 选择工作文件夹 - - + + Header Exists 头文件已存在 - - + + Header file "%1" already exists! 头文件"%1"已存在! - + Source Exists 源文件已存在! - + Source file "%1" already exists! 源文件"%1"已存在! - + Can't commit! 无法提交! - + The following files are in conflicting: 下列文件处于冲突状态,请解决后重新添加和提交: - + Commit Message 提交信息 - + Commit Message: 提交信息: - + Commit Failed 提交失败 - + Commit message shouldn't be empty! 提交信息不能为空! @@ -6949,22 +6954,22 @@ Are you really want to continue? 小熊猫Dev-C++项目文件 (*.dev) - + New project fail 新建项目失败 - + Can't assign project template 无法使用模板创建项目 - + Remove file 删除文件 - + Remove the file from disk? 同时从硬盘上删除文件? @@ -6973,27 +6978,27 @@ Are you really want to continue? 无标题 - + New Project File Name 新的项目文件名 - + File Name: 文件名: - + File Already Exists! 文件已存在! - + File '%1' already exists! 文件'%1'已经存在! - + Add to project 添加到项目 @@ -7059,78 +7064,78 @@ Are you really want to continue? 请查看“工具输出”面板中的详细信息。 - + Red Panda C++ project file (*.dev) 小熊猫C++项目文件(*.dev) - + Rename Error 重命名出错 - + Symbol '%1' is defined in system header. 符号'%1'在系统头文件中定义,无法修改。 - + New Name 新名称 - - - + + + Replace Error 替换出错 - + Can't open file '%1' for replace! 无法打开文件'%1'进行替换! - + Contents has changed since last search! 内容和上次查找时不一致。 - + Rich Text Format Files (*.rtf) RTF格式文件 (*.rtf) - + HTML Files (*.html) HTML文件 (*.html) - + The current problem set is not empty. 当前的试题集不是空的。 - + Problem %1 试题%1 - - + + Problem Set Files (*.pbs) 试题集文件 (*.pbs) - - + + Load Error 载入失败 - + Problem Case %1 试题案例%1 @@ -7146,9 +7151,9 @@ Are you really want to continue? - - - + + + Error 错误 @@ -7220,9 +7225,9 @@ Are you really want to continue? - - - + + + Confirm Convertion 确认转换 @@ -7235,35 +7240,35 @@ Are you really want to continue? - - - + + + The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue? 当前编辑器中的文件将会使用%1编码保存。<br />这项操作无法被撤回。<br />你确定要继续吗? - + New Watch Expression 新监视表达式 - + Enter Watch Expression (it is recommended to use 'this->' for class members): 输入监视表达式 - + Parsing file %1 of %2: "%3" (%1/%2)正在解析文件"%3" - - + + Done parsing %1 files in %2 seconds 完成%1个文件的解析,用时%2秒 - + (%1 files per second) (每秒%1个文件) @@ -7553,32 +7558,32 @@ Are you really want to continue? 案例运行超时 - + Time limit exceeded! 运行时间超限! - + Memory limit exceeded! 运行内存超限! - + The runner process '%1' failed to start. 无法启动程序运行进程'%1'。 - + The last waitFor...() function timed out. waitFor()函数等待超时。 - + An error occurred when attempting to write to the runner process. 在向程序运行进程写入内容时出错。 - + An error occurred when attempting to read from the runner process. 在从程序运行进程读取内容时出错。 @@ -9308,18 +9313,18 @@ Are you really want to continue? 析构函数 - - - + + + Can't open file '%1' for read. 无法读取文件'%1'. - - - + + + Can't open file '%1' for write. 无法写入文件'%1'. @@ -9809,32 +9814,32 @@ Are you really want to continue? 要查找的关键字 - + Replace with: 替换为: - + Options: 选项: - + Case Sensitive 区分大小写 - + Whole words only 整个单词 - + Wrap Around 循环查找 - + Regular Expression 正则表达式 @@ -9843,57 +9848,57 @@ Are you really want to continue? 替换时提示 - + Scope: 范围: - + Global 全局 - + Selection 选中文字 - + Origin: 起点: - + From cursor 从光标处 - + Entire scope 整个范围 - + Close after search 找到后关闭对话框 - + Find Previous 查找前一个 - + Find Next 查找下一个 - + Replace All 全部替换 - + Close 关闭 @@ -9939,7 +9944,7 @@ Are you really want to continue? 在文件中查找 - + Replace 替换 @@ -10006,92 +10011,92 @@ Are you really want to continue? 在文件中查找 - + *.* *.* - + Text to Find: 要查找的内容: - + Filters: 文件过滤: - + ... ... - + Folder: 文件夹: - + Search in subfolders 在子文件夹中查找 - + Where: 在哪些文件中查找: - + Current File 当前文件 - + Files In Project 项目中的文件 - + Open Files 已打开的文件 - + Folder 文件夹 - + Options: 选项: - + Whole words only 整个单词 - + Case Sensitive 区分大小写 - + Regular Expression 正则表达式 - + Find 查找 - + Replace 替换 - + Cancel 取消 @@ -10125,20 +10130,20 @@ Are you really want to continue? - - - + + + Searching... 正在查找... - + Abort 中止 - + Choose Folder 选择文件夹 @@ -10391,8 +10396,8 @@ Are you really want to continue? - - + + Compiler Set @@ -10400,7 +10405,7 @@ Are you really want to continue? - + Compiler @@ -10412,7 +10417,7 @@ Are you really want to continue? 自动链接 - + @@ -10488,15 +10493,15 @@ Are you really want to continue? 杂项 - - + + Program Runner 程序运行 - + Problem Set 试题集 @@ -10556,7 +10561,7 @@ Are you really want to continue? - + diff --git a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts index c6f17dba..6b8ff0f8 100644 --- a/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts +++ b/RedPandaIDE/translations/RedPandaIDE_zh_TW.ts @@ -1930,6 +1930,10 @@ Expected Output + + Redirect STDERR to Tools output panel + + FileAssociationModel diff --git a/RedPandaIDE/widgets/linenumbertexteditor.cpp b/RedPandaIDE/widgets/linenumbertexteditor.cpp index b47c21e9..100f35de 100644 --- a/RedPandaIDE/widgets/linenumbertexteditor.cpp +++ b/RedPandaIDE/widgets/linenumbertexteditor.cpp @@ -61,6 +61,13 @@ void LineNumberTextEditor::updateLineNumberArea(const QRect &rect, int dy) updateLineNumberAreaWidth(0); } +void LineNumberTextEditor::clearStartFormat() +{ + moveCursor(QTextCursor::Start); + QTextCursor cursor = textCursor(); + cursor.setCharFormat(QTextCharFormat()); +} + const QColor &LineNumberTextEditor::lineNumberAreaCurrentLine() const { return mLineNumberAreaCurrentLine; @@ -74,6 +81,20 @@ void LineNumberTextEditor::setLineNumberAreaCurrentLine(const QColor &newLineNum emit lineNumberAreaCurrentLineChanged(); } +void LineNumberTextEditor::clearFormat() +{ + QTextCursor cursor = textCursor(); + cursor.select(QTextCursor::Document); + cursor.setCharFormat(QTextCharFormat()); + cursor.clearSelection(); +} + +void LineNumberTextEditor::clearAll() +{ + clear(); + clearStartFormat(); +} + const QColor &LineNumberTextEditor::lineNumberAreaBackground() const { return mLineNumberAreaBackground; diff --git a/RedPandaIDE/widgets/linenumbertexteditor.h b/RedPandaIDE/widgets/linenumbertexteditor.h index 461136d2..911d928b 100644 --- a/RedPandaIDE/widgets/linenumbertexteditor.h +++ b/RedPandaIDE/widgets/linenumbertexteditor.h @@ -37,6 +37,10 @@ public: const QColor &lineNumberAreaCurrentLine() const; void setLineNumberAreaCurrentLine(const QColor &newLineNumberAreaCurrentLine); + void clearFormat(); + + void clearAll(); + signals: void lineNumberAreaCurrentLineChanged(); @@ -47,6 +51,8 @@ private slots: void updateLineNumberAreaWidth(int newBlockCount); void highlightCurrentLine(); void updateLineNumberArea(const QRect &rect, int dy); +private: + void clearStartFormat(); private: QWidget *lineNumberArea; diff --git a/libs/qsynedit/qsynedit/qsynedit.cpp b/libs/qsynedit/qsynedit/qsynedit.cpp index 85fff9aa..eff3966d 100644 --- a/libs/qsynedit/qsynedit/qsynedit.cpp +++ b/libs/qsynedit/qsynedit/qsynedit.cpp @@ -1538,6 +1538,8 @@ int QSynEdit::calcIndentSpaces(int line, const QString& lineText, bool addIndent line = std::min(line, mDocument->count()+1); if (line<=1) return 0; + if (lineText.startsWith("//")) + return 0; if (mFormatter) { return mFormatter->calcIndentSpaces(line,lineText,addIndent,this); } diff --git a/libs/qsynedit/qsynedit_zh_CN.ts b/libs/qsynedit/qsynedit_zh_CN.ts index 804cfc20..b92e0e8c 100644 --- a/libs/qsynedit/qsynedit_zh_CN.ts +++ b/libs/qsynedit/qsynedit_zh_CN.ts @@ -4294,17 +4294,22 @@ - + Can't load codec '%1'! 无法加载字符编码"%1"! - + + This is a binaray File! + + + + Can't open file '%1' for save! 无法保存文件"%1"! - + Data not correctly writed to file '%1'. 数据未能正确写入文件"%1"。 diff --git a/libs/redpanda_qt_utils/qt_utils/utils.cpp b/libs/redpanda_qt_utils/qt_utils/utils.cpp index 87ea0d8f..cbc04cae 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.cpp +++ b/libs/redpanda_qt_utils/qt_utils/utils.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef Q_OS_WIN #include #include @@ -734,3 +735,11 @@ bool isBinaryContent(const QByteArray &text) } return false; } + +void clearQPlainTextEditFormat(QTextEdit *editor) +{ + QTextCursor cursor = editor->textCursor(); + cursor.select(QTextCursor::Document); + cursor.setCharFormat(QTextCharFormat()); + cursor.clearSelection(); +} diff --git a/libs/redpanda_qt_utils/qt_utils/utils.h b/libs/redpanda_qt_utils/qt_utils/utils.h index e4a4af4d..ee194853 100644 --- a/libs/redpanda_qt_utils/qt_utils/utils.h +++ b/libs/redpanda_qt_utils/qt_utils/utils.h @@ -86,6 +86,9 @@ QList splitByteArrayToLines(const QByteArray& content); QString trimRight(const QString& s); QString trimLeft(const QString& s); +class QTextEdit; +void clearQPlainTextEditFormat(QTextEdit* editor); + int countLeadingWhitespaceChars(const QString& line); bool stringIsBlank(const QString& s); diff --git a/libs/redpanda_qt_utils/qt_utils_zh_CN.ts b/libs/redpanda_qt_utils/qt_utils_zh_CN.ts index f975fce9..f0f97fc4 100644 --- a/libs/redpanda_qt_utils/qt_utils_zh_CN.ts +++ b/libs/redpanda_qt_utils/qt_utils_zh_CN.ts @@ -125,7 +125,7 @@ QObject - + Index %1 out of range 下标%1越界