* work save: syntax error display in the editor

This commit is contained in:
royqh1979@gmail.com 2021-06-24 16:05:19 +08:00
parent 350be90c74
commit 1f403198e5
22 changed files with 486 additions and 34 deletions

View File

@ -17,6 +17,7 @@ SOURCES += \
compiler/filecompiler.cpp \
editor.cpp \
editorlist.cpp \
iconsmanager.cpp \
main.cpp \
mainwindow.cpp \
qsynedit/CodeFolding.cpp \
@ -59,6 +60,7 @@ HEADERS += \
compiler/filecompiler.h \
editor.h \
editorlist.h \
iconsmanager.h \
mainwindow.h \
qsynedit/CodeFolding.h \
qsynedit/Constants.h \

View File

@ -15,6 +15,7 @@ struct CompileIssue {
QString filename;
int line;
int column;
int endColumn;
QString description;
CompileIssueType type;
};

View File

@ -101,6 +101,7 @@ int Compiler::getColunmnFromOutputLine(QString &line)
}
if (pos>=0) {
result = line.mid(0,pos).toInt();
if (result > 0)
line.remove(0,pos+1);
}
return result;
@ -141,6 +142,7 @@ void Compiler::processOutput(QString &line)
PCompileIssue issue = std::make_shared<CompileIssue>();
QString description;
issue->type = CompileIssueType::Other;
issue->endColumn = -1;
if (line.startsWith(inFilePrefix)) {
line.remove(0,inFilePrefix.length());
issue->filename = getFileNameFromOutputLine(line);
@ -166,16 +168,54 @@ void Compiler::processOutput(QString &line)
// Ignore code snippets that GCC produces
// they always start with a space
if (line.length()>0 && line[0] == ' ') {
if (!mLastIssue)
return;
QString s = line.trimmed();
if (s.startsWith('|') && s.indexOf('^')) {
int pos = 0;
while (pos < s.length()) {
if (s[pos]=='^')
break;
pos++;
}
if (pos<s.length()) {
int i=pos+1;
while (i<s.length()) {
if (s[i]!='~' && s[i]!='^')
break;
i++;
}
mLastIssue->endColumn = mLastIssue->column+i-pos;
emit compileIssue(mLastIssue);
mLastIssue.reset();
}
}
return;
}
if (mLastIssue) {
emit compileIssue(mLastIssue);
mLastIssue.reset();
}
// assume regular main.cpp:line:col: message
issue->filename = getFileNameFromOutputLine(line);
issue->line = getLineNumberFromOutputLine(line);
if (issue->line > 0)
if (issue->line > 0) {
issue->column = getColunmnFromOutputLine(line);
if (issue->column>0)
issue->type = getIssueTypeFromOutputLine(line);
else
issue->type = CompileIssueType::Error; //linkage error
} else {
issue->column = -1;
issue->type = getIssueTypeFromOutputLine(line);
}
issue->description = line.trimmed();
if (issue->line<=0) {
emit compileIssue(issue);
} else
mLastIssue = issue;
}
void Compiler::stopCompile()
@ -316,7 +356,6 @@ void Compiler::runCommand(const QString &cmd, const QString &arguments, const Q
[&](){
errorOccurred= true;
});
process.connect(&process, &QProcess::readyReadStandardError,[&process,this](){
this->error(QString::fromLocal8Bit( process.readAllStandardError()));
});

View File

@ -56,6 +56,7 @@ protected:
QString mOutputFile;
int mErrorCount;
int mWarningCount;
PCompileIssue mLastIssue;
private:
bool mStop;

View File

@ -33,6 +33,7 @@ void CompilerManager::compile(const QString& filename, const QByteArray& encodin
mCompileErrorCount = 0;
mCompiler = new FileCompiler(filename,encoding,silent,onlyCheckSyntax);
connect(mCompiler, &Compiler::compileFinished, this ,&CompilerManager::onCompileFinished);
connect(mCompiler, &Compiler::compileIssue, this, &CompilerManager::onCompileIssue);
connect(mCompiler, &Compiler::compileFinished, pMainWindow, &MainWindow::onCompileFinished);
connect(mCompiler, &Compiler::compileOutput, pMainWindow, &MainWindow::onCompileLog);
connect(mCompiler, &Compiler::compileIssue, pMainWindow, &MainWindow::onCompileIssue);
@ -64,8 +65,8 @@ bool CompilerManager::canCompile(const QString &filename)
void CompilerManager::onCompileFinished()
{
QMutexLocker locker(&compileMutex);
mCompiler=nullptr;
delete mCompiler;
mCompiler=nullptr;
}
void CompilerManager::onRunnerTerminated()
@ -75,6 +76,11 @@ void CompilerManager::onRunnerTerminated()
mRunner=nullptr;
}
void CompilerManager::onCompileIssue(PCompileIssue)
{
mCompileErrorCount ++;
}
int CompilerManager::syntaxCheckErrorCount() const
{
return mSyntaxCheckErrorCount;

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QMutex>
#include "../utils.h"
#include "../common.h"
class ExecutableRunner;
class Compiler;
@ -26,6 +27,8 @@ public:
private slots:
void onCompileFinished();
void onRunnerTerminated();
void onCompileIssue(PCompileIssue issue);
private:
Compiler* mCompiler;
int mCompileErrorCount;

View File

@ -20,6 +20,8 @@
#include "qsynedit/Constants.h"
#include <QGuiApplication>
#include <QClipboard>
#include <QPainter>
#include "iconsmanager.h"
using namespace std;
@ -53,7 +55,9 @@ Editor::Editor(QWidget *parent, const QString& filename,
mFilename(filename),
mParentPageControl(parentPageControl),
mInProject(inProject),
mIsNew(isNew)
mIsNew(isNew),
mSyntaxErrorColor(QColorConstants::Red),
mSyntaxWaringColor("orange")
{
if (mFilename.isEmpty()) {
newfileCount++;
@ -339,6 +343,92 @@ void Editor::keyPressEvent(QKeyEvent *event)
}
}
void Editor::onGutterPaint(QPainter &painter, int aLine, int X, int Y)
{
// Get point where to draw marks
//X := (fText.Gutter.RealGutterWidth(fText.CharWidth) - fText.Gutter.RightOffset) div 2 - 3;
X = 5;
Y += (this->textHeight() - 16) / 2;
PSyntaxIssueList lst = getSyntaxIssuesAtLine(aLine);
if (lst) {
bool hasError=false;
for (PSyntaxIssue issue : *lst) {
if (issue->issueType == CompileIssueType::Error) {
hasError = true;
break;;
}
}
if (hasError) {
painter.drawPixmap(X,Y,*(pIconsManager->syntaxError()));
} else {
painter.drawPixmap(X,Y,*(pIconsManager->syntaxWarning()));
}
}
// if fActiveLine = Line then begin // prefer active line over breakpoints
// dmMain.GutterImages.Draw(ACanvas, X, Y, 1);
// drawn:=True;
// end else if HasBreakpoint(Line) <> -1 then begin
// dmMain.GutterImages.Draw(ACanvas, X, Y, 0);
// drawn:=True;
// end else if fErrorLine = Line then begin
// dmMain.GutterImages.Draw(ACanvas, X, Y, 2);
// drawn:=True;
// end;
// idx := CBUtils.FastIndexOf(fErrorList, Line);
// if idx>=0 then begin
// isError := False;
// lst:=TList(fErrorList.Objects[idx]);
// for j:=0 to lst.Count-1 do begin
// if PSyntaxError(lst[j])^.errorType = setError then begin
// isError := True;
// break;
// end;
// end;
// if isError then
// dmMain.GutterImages.Draw(ACanvas, X, Y, 2)
// else if not drawn then
// dmMain.GutterImages.Draw(ACanvas, X, Y, 3);
// end;
// Inc(Y, fText.LineHeight);
// end;
}
void Editor::onGetEditingAreas(int Line, SynEditingAreaList &areaList)
{
areaList.clear();
// if (fTabStopBegin >=0) and (fTabStopY=Line) then begin
// areaType:=eatEditing;
// System.new(p);
// spaceCount := fText.LeftSpacesEx(fLineBeforeTabStop,True);
// spaceBefore := Length(fLineBeforeTabStop) - Length(TrimLeft(fLineBeforeTabStop));
// p.beginX := fTabStopBegin + spaceCount - spaceBefore ;
// p.endX := fTabStopEnd + spaceCount - spaceBefore ;
// p.color := dmMain.Cpp.StringAttri.Foreground;
// areaList.Add(p);
// ColBorder := dmMain.Cpp.StringAttri.Foreground;
// Exit;
// end;
// StrToThemeColor(tc,devEditor.Syntax.Values[cWN]);
PSyntaxIssueList lst = getSyntaxIssuesAtLine(Line);
if (lst) {
for (PSyntaxIssue issue: *lst) {
PSynEditingArea p=std::make_shared<SynEditingArea>();
p->beginX = issue->col;
p->endX = issue->endCol;
if (issue->issueType == CompileIssueType::Error) {
p->color = mSyntaxErrorColor;
} else {
p->color = mSyntaxWaringColor;
}
p->type = SynEditingAreaType::eatWaveUnderLine;
areaList.append(p);
}
}
}
void Editor::copyToClipboard()
{
if (pSettings->editor().copySizeLimit()) {
@ -409,7 +499,21 @@ void Editor::copyAsHTML()
QGuiApplication::clipboard()->setMimeData(mimeData);
}
void Editor::addSyntaxIssues(int line, int startChar, CompileIssueType errorType, const QString &hint)
void Editor::setCaretPosition(int line, int col)
{
this->uncollapseAroundLine(line);
this->setCaretXYCentered(true,BufferCoord{col,line});
}
void Editor::setCaretPositionAndActivate(int line, int col)
{
this->uncollapseAroundLine(line);
if (!this->hasFocus())
this->activate();
this->setCaretXYCentered(true,BufferCoord{col,line});
}
void Editor::addSyntaxIssues(int line, int startChar, int endChar, CompileIssueType errorType, const QString &hint)
{
PSyntaxIssue pError;
BufferCoord p;
@ -426,9 +530,12 @@ void Editor::addSyntaxIssues(int line, int startChar, CompileIssueType errorType
if (startChar >= lines()->getString(line-1).length()) {
start = 1;
token = lines()->getString(line-1);
} else {
} else if (endChar < 1) {
if (!GetHighlighterAttriAtRowColEx(p,token,tokenType,tokenKind,start,attr))
return;
} else {
start = startChar;
token = lines()->getString(line-1).mid(start-1,endChar-startChar);
}
pError->startChar = start;
pError->endChar = start + token.length();
@ -501,16 +608,16 @@ bool Editor::hasPrevSyntaxIssue() const
return false;
}
Editor::PSyntaxIssueList Editor::getErrorsAtLine(int line)
Editor::PSyntaxIssueList Editor::getSyntaxIssuesAtLine(int line)
{
if (mSyntaxIssues.contains(line))
return mSyntaxIssues[line];
return PSyntaxIssueList();
}
Editor::PSyntaxIssue Editor::getErrorAtPosition(const BufferCoord &pos)
Editor::PSyntaxIssue Editor::getSyntaxIssueAtPosition(const BufferCoord &pos)
{
PSyntaxIssueList lst = getErrorsAtLine(pos.Line);
PSyntaxIssueList lst = getSyntaxIssuesAtLine(pos.Line);
for (PSyntaxIssue issue: *lst) {
if (issue->startChar<=pos.Char && pos.Char<=issue->endChar)
return issue;

View File

@ -97,15 +97,17 @@ public:
void copyToClipboard() override;
void cutToClipboard() override;
void copyAsHTML();
void setCaretPosition(int line,int col);
void setCaretPositionAndActivate(int line,int col);
void addSyntaxIssues(int line, int startChar, CompileIssueType errorType, const QString& hint);
void addSyntaxIssues(int line, int startChar, int endChar, CompileIssueType errorType, const QString& hint);
void clearSyntaxIssues();
void gotoNextSyntaxIssue();
void gotoPrevSyntaxIssue();
bool hasPrevSyntaxIssue() const;
bool hasNextSyntaxIssue() const;
PSyntaxIssueList getErrorsAtLine(int line);
PSyntaxIssue getErrorAtPosition(const BufferCoord& pos);
PSyntaxIssueList getSyntaxIssuesAtLine(int line);
PSyntaxIssue getSyntaxIssueAtPosition(const BufferCoord& pos);
signals:
@ -139,6 +141,9 @@ private:
bool mInProject;
bool mIsNew;
QMap<int,PSyntaxIssueList> mSyntaxIssues;
QColor mSyntaxErrorColor;
QColor mSyntaxWaringColor;
int mSyntaxErrorLine;
// QWidget interface
protected:
@ -146,6 +151,11 @@ protected:
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;
void keyPressEvent(QKeyEvent *event) override;
// SynEdit interface
protected:
void onGutterPaint(QPainter &painter, int aLine, int X, int Y) override;
void onGetEditingAreas(int Line, SynEditingAreaList &areaList) override;
};
#endif // EDITOR_H

View File

@ -167,15 +167,17 @@ bool EditorList::closeAll(bool force) {
Editor* EditorList::getOpenedEditorByFilename(const QString &filename)
{
QFileInfo fileInfo(filename);
QString fullname = fileInfo.absoluteFilePath();
for (int i=0;i<mLeftPageWidget->count();i++) {
Editor* e = static_cast<Editor*>(mLeftPageWidget->widget(i));
if (e->filename() == filename) {
if (e->filename() == fullname) {
return e;
}
}
for (int i=0;i<mRightPageWidget->count();i++) {
Editor* e = static_cast<Editor*>(mRightPageWidget->widget(i));
if (e->filename() == filename) {
if (e->filename() == fullname) {
return e;
}
}
@ -184,12 +186,16 @@ Editor* EditorList::getOpenedEditorByFilename(const QString &filename)
Editor *EditorList::getEditorByFilename(const QString &filename)
{
QFileInfo fileInfo(filename);
QString fullname = fileInfo.absoluteFilePath();
//check if an editor is already openned
Editor* e=getOpenedEditorByFilename(filename);
Editor* e=getOpenedEditorByFilename(fullname);
if (e!=nullptr)
return e;
//Todo: check if is in the project
//Create a new editor
return newEditor(filename,ENCODING_AUTO_DETECT,false,false);
if (fileInfo.exists())
return newEditor(fullname,ENCODING_AUTO_DETECT,false,false);
return nullptr;
}

View File

@ -450,5 +450,9 @@
<file>images/newlook64/087-update.png</file>
<file>images/newlook64/088-watch.png</file>
<file>images/newlook64/089-watch-tm.png</file>
<file>images/editor/breakpoint.png</file>
<file>images/editor/currentline.png</file>
<file>images/editor/syntaxerror.png</file>
<file>images/editor/syntaxwarning.png</file>
</qresource>
</RCC>

View File

@ -0,0 +1,31 @@
#include "iconsmanager.h"
IconsManager* pIconsManager;
IconsManager::IconsManager(QObject *parent) : QObject(parent)
{
mSyntaxError = std::make_shared<QPixmap>(":/icons/images/editor/syntaxerror.png");
mSyntaxWarning = std::make_shared<QPixmap>(":/icons/images/editor/syntaxwarning.png");
mBreakpoint = std::make_shared<QPixmap>(":/icons/images/editor/breakpoint.png");
mCurrentLine = std::make_shared<QPixmap>(":/icons/images/editor/currentline.png");
}
PIcon IconsManager::syntaxError() const
{
return mSyntaxError;
}
PIcon IconsManager::syntaxWarning() const
{
return mSyntaxWarning;
}
PIcon IconsManager::breakpoint() const
{
return mBreakpoint;
}
PIcon IconsManager::currentLine() const
{
return mCurrentLine;
}

View File

@ -0,0 +1,32 @@
#ifndef ICONSMANAGER_H
#define ICONSMANAGER_H
#include <QObject>
#include <QPixmap>
#include <memory>
using PIcon = std::shared_ptr<QPixmap>;
class IconsManager : public QObject
{
Q_OBJECT
public:
explicit IconsManager(QObject *parent = nullptr);
PIcon syntaxError() const;
PIcon syntaxWarning() const;
PIcon breakpoint() const;
PIcon currentLine() const;
signals:
private:
PIcon mSyntaxError;
PIcon mSyntaxWarning;
PIcon mBreakpoint;
PIcon mCurrentLine;
};
extern IconsManager* pIconsManager;
#endif // ICONSMANAGER_H

View File

@ -11,6 +11,7 @@
#include <QStringList>
#include "common.h"
#include "colorscheme.h"
#include "iconsmanager.h"
Settings* createAppSettings(const QString& filepath = QString()) {
QString filename;
@ -74,6 +75,7 @@ int main(int argc, char *argv[])
//Color scheme settings must be loaded after translation
pColorManager = new ColorManager();
pIconsManager = new IconsManager();
MainWindow mainWindow;
pMainWindow = &mainWindow;

View File

@ -25,6 +25,7 @@ MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow),
mMessageControlChanged(false),
mTabMessagesTogglingState(false),
mCheckSyntaxInBack(false)
{
ui->setupUi(this);
@ -40,7 +41,7 @@ MainWindow::MainWindow(QWidget *parent)
ui->statusbar->addWidget(mFileModeStatus);
mEditorList = new EditorList(ui->EditorTabsLeft,
ui->EditorTabsRight,
ui->EditorPanelSplitter,
ui->splitterEditorPanel,
ui->EditorPanel);
setupActions();
ui->EditorTabsRight->setVisible(false);
@ -73,10 +74,12 @@ MainWindow::MainWindow(QWidget *parent)
ui->actionEncode_in_ANSI->setCheckable(true);
ui->actionEncode_in_UTF_8->setCheckable(true);
openCloseMessageSheet(false);
mPreviousHeight = 250;
updateEditorActions();
applySettings();
openCloseMessageSheet(false);
mPreviousHeight = 250;
}
MainWindow::~MainWindow()
@ -256,7 +259,12 @@ void MainWindow::openCloseMessageSheet(bool open)
{
// if Assigned(fReportToolWindow) then
// Exit;
if (mTabMessagesTogglingState)
return;
mTabMessagesTogglingState = true;
auto action = finally([this]{
mTabMessagesTogglingState = false;
});
// Switch between open and close
if (open) {
QList<int> sizes = ui->splitterMessages->sizes();
@ -280,6 +288,7 @@ void MainWindow::openCloseMessageSheet(bool open)
handle->setEnabled(open);
int idxClose = ui->tabMessages->indexOf(ui->tabClose);
ui->tabMessages->setTabVisible(idxClose,open);
mTabMessagesTogglingState = false;
}
@ -383,7 +392,9 @@ void MainWindow::onCompileIssue(PCompileIssue issue)
if (line > e->lines()->count())
return;
int col = std::min(issue->column,e->lines()->getString(line-1).length()+1);
e->addSyntaxIssues(line,col,issue->type,issue->description);
if (col < 1)
col = e->lines()->getString(line-1).length()+1;
e->addSyntaxIssues(line,col,issue->endColumn,issue->type,issue->description);
}
}
}
@ -592,8 +603,7 @@ void MainWindow::on_tableIssues_doubleClicked(const QModelIndex &index)
if (editor == nullptr)
return;
//editor->setCursorPosition(issue->line-1,issue->column-1);
editor->activate();
editor->setCaretPositionAndActivate(issue->line,issue->column);
}
void MainWindow::on_actionEncode_in_ANSI_triggered()
@ -657,7 +667,14 @@ void MainWindow::on_actionConvert_to_UTF_8_triggered()
void MainWindow::on_tabMessages_tabBarClicked(int index)
{
mMessageControlChanged = false;
if (index == ui->tabMessages->currentIndex()) {
openCloseMessageSheet(!ui->splitterMessages->handle(1)->isEnabled());
}
}
void MainWindow::on_tabMessages_currentChanged(int index)
{
mMessageControlChanged = true;
int idxClose = ui->tabMessages->indexOf(ui->tabClose);
if (index == idxClose) {
openCloseMessageSheet(false);
@ -665,3 +682,8 @@ void MainWindow::on_tabMessages_tabBarClicked(int index)
openCloseMessageSheet(true);
}
}
void MainWindow::on_tabMessages_tabBarDoubleClicked(int index)
{
}

View File

@ -90,6 +90,10 @@ private slots:
void on_tabMessages_tabBarClicked(int index);
void on_tabMessages_currentChanged(int index);
void on_tabMessages_tabBarDoubleClicked(int index);
public slots:
void onCompileLog(const QString& msg);
void onCompileIssue(PCompileIssue issue);
@ -113,6 +117,7 @@ private:
QComboBox* mCompilerSet;
CompilerManager* mCompilerManager;
bool mMessageControlChanged;
bool mTabMessagesTogglingState;
bool mCheckSyntaxInBack;
int mPreviousHeight;

View File

@ -37,6 +37,9 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="handleWidth">
<number>1</number>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
</property>
@ -65,6 +68,9 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="handleWidth">
<number>1</number>
</property>
<property name="childrenCollapsible">
<bool>false</bool>
</property>
@ -113,10 +119,13 @@
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="EditorPanelSplitter">
<widget class="QSplitter" name="splitterEditorPanel">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="handleWidth">
<number>1</number>
</property>
<widget class="QTabWidget" name="EditorTabsLeft">
<property name="currentIndex">
<number>-1</number>
@ -164,7 +173,7 @@
<enum>QTabWidget::South</enum>
</property>
<property name="currentIndex">
<number>5</number>
<number>0</number>
</property>
<widget class="QWidget" name="tabIssues">
<attribute name="icon">

View File

@ -275,6 +275,22 @@ void SynEdit::setCaretXYCentered(bool ForceToMiddle, const BufferCoord &value)
ensureCursorPosVisibleEx(true); // but here after block has been set
}
void SynEdit::uncollapseAroundLine(int line)
{
while (true) { // Open up the closed folds around the focused line until we can see the line we're looking for
PSynEditFoldRange fold = foldHidesLine(line);
if (fold)
uncollapse(fold);
else
break;
}
}
PSynEditFoldRange SynEdit::foldHidesLine(int line)
{
return foldAroundLineEx(line, true, false, true);
}
void SynEdit::setInsertMode(bool value)
{
if (mInserting != value) {
@ -3160,6 +3176,11 @@ void SynEdit::doScrolled(int)
invalidate();
}
int SynEdit::textHeight() const
{
return mTextHeight;
}
bool SynEdit::readOnly() const
{
return mReadOnly;

View File

@ -208,6 +208,8 @@ public:
void setCaretXY(const BufferCoord& value);
void setCaretXYEx(bool CallEnsureCursorPos, BufferCoord value);
void setCaretXYCentered(bool ForceToMiddle, const BufferCoord& value);
void uncollapseAroundLine(int line);
PSynEditFoldRange foldHidesLine(int line);
int maxScrollWidth() const;
int maxScrollHeight() const;
@ -313,6 +315,8 @@ public:
bool canUndo() const;
bool canRedo() const;
int textHeight() const;
signals:
void Changed();

View File

@ -421,7 +421,7 @@ void SynEditTextPainter::PaintEditAreas(const SynEditingAreaList &areaList)
int lastX=rc.left();
int lastY=rc.bottom()-offset;
int t = rc.left();
while (t<=rc.right()) {
while (t<rc.right()) {
t+=3;
if (t>rc.right())
t = rc.right();

View File

@ -6,6 +6,7 @@
#include <QDir>
#include "systemconsts.h"
#include <QDebug>
#include <QMessageBox>
const char ValueToChar[28] = {'0', '1', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
@ -984,8 +985,122 @@ void Settings::CompilerSet::setOption(PCompilerOption &option, char valueChar)
option->value = charToValue(valueChar);
}
static void checkDirs(const QStringList& dirlist, QString& gooddirs, QString& baddirs) {
gooddirs = "";
baddirs = "";
for (int i=0; i<dirlist.count();i++) {
QDir dir(dirlist[i]);
if (!dir.exists()) {
if (baddirs.isEmpty()) {
baddirs = dirlist[i];
} else {
baddirs += ";" + dirlist[i];
}
} else {
if (gooddirs.isEmpty()) {
gooddirs = dirlist[i];
} else {
gooddirs += ";" + dirlist[i];
}
}
}
}
bool Settings::CompilerSet::dirsValid(QString &msg)
{
QString goodbin, badbin, goodlib, badlib, goodinc, badinc, goodinccpp, badinccpp;
msg = "";
if (mBinDirs.count()>0) {// we need some bin dir, so treat count=0 as an error too
checkDirs(mBinDirs,goodbin,badbin);
if (!badbin.isEmpty()) {
msg += QObject::tr("The following %1 directories don't exist:").arg(
QObject::tr("binary")
);
msg += "<br />";
msg += badbin.replace(';',"<br />");
msg += "<br />";
msg += "<br />";
return false;
}
} else {
msg += QObject::tr("No %1 directories have been specified.").arg(
QObject::tr("binary")
);
msg += "<br />";
msg += "<br />";
return false;
}
checkDirs(mCIncludeDirs,goodbin,badbin);
if (!badbin.isEmpty()) {
msg += QObject::tr("The following %1 directories don't exist:").arg(
QObject::tr("C include")
);
msg += "<br />";
msg += badbin.replace(';',"<br />");
msg += "<br />";
msg += "<br />";
return false;
}
checkDirs(mCppIncludeDirs,goodbin,badbin);
if (!badbin.isEmpty()) {
msg += QObject::tr("The following %1 directories don't exist:").arg(
QObject::tr("C++ include")
);
msg += "<br />";
msg += badbin.replace(';',"<br />");
msg += "<br />";
msg += "<br />";
return false;
}
checkDirs(mLibDirs,goodbin,badbin);
if (!badbin.isEmpty()) {
msg += QObject::tr("The following %1 directories don't exist:").arg(
QObject::tr("C++ include")
);
msg += "<br />";
msg += badbin.replace(';',"<br />");
msg += "<br />";
msg += "<br />";
return false;
}
if (!msg.isEmpty())
return false;
else
return true;
}
bool Settings::CompilerSet::validateExes(QString &msg)
{
msg ="";
if (!QFile(mCCompiler).exists()) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("C Compiler")
.arg(mCCompiler);
}
if (!QFile(mCppCompiler).exists()) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("C++ Compiler")
.arg(mCppCompiler);
}
if (!QFile(mMake).exists()) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("Maker")
.arg(mMake);
}
if (!QFile(mDebugger).exists()) {
msg += QObject::tr("Cannot find the %1 \"%2\"")
.arg("Maker")
.arg(mDebugger);
}
if (!msg.isEmpty())
return false;
else
return true;
}
@ -1766,8 +1881,30 @@ void Settings::CompilerSets::loadSets()
PCompilerSet pCurrentSet = defaultSet();
if (pCurrentSet) {
QString msg;
if (!pCurrentSet->dirsValid(msg)) {
if (!pCurrentSet->dirsValid(msg) || !pCurrentSet->validateExes(msg)) {
if (QMessageBox::warning(nullptr,tr("Confirm"),
QObject::tr("The following problems were found during validation of compiler set \"%1\":")
.arg(pCurrentSet->name())
+"<br /><br />"
+msg
+"Would you like Dev-C++ to remove them for you and add the default paths to the valid paths?<br /><br />Leaving those directories will lead to problems during compilation.<br /><br />Unless you know exactly what you're doing, it is recommended that you click Yes.",
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Ok) {
clearSets();
findSets();
saveSets();
if ( mList.size() <= mDefaultIndex)
mDefaultIndex = mList.size()-1;
} else {
return;
}
pCurrentSet = defaultSet();
if (!pCurrentSet) {
return;
}
saveSet(mDefaultIndex);
if (pCurrentSet->binDirs().count()>0) {
pCurrentSet->setProperties(pCurrentSet->binDirs()[0]);
}
}
}
}

View File

@ -370,8 +370,10 @@ public:
char getOptionValue(const QString& setting);
void setOption(const QString& setting, char valueChar);
void setOption(PCompilerOption& option, char valueChar);
void setProperties(const QString& binDir);
bool dirsValid(QString& msg);
bool validateExes(QString& msg);
//properties
const QString& CCompiler() const;
void setCCompiler(const QString& name);
@ -427,7 +429,6 @@ public:
int charToValue(char valueChar);
// Initialization
void setProperties(const QString& binDir);
void setExecutables();
void setDirectories(const QString& folder);
void setUserInput();

View File

@ -219,6 +219,9 @@ void CompilerSetOptionWidget::on_btnFindCompilers_pressed()
pSettings->compilerSets().clearSets();
pSettings->compilerSets().findSets();
doLoad();
if (pSettings->compilerSets().size()==0) {
QMessageBox::warning(this,tr("Failed"),tr("Can't find any compiler."));
}
}
void CompilerSetOptionWidget::on_btnAddBlankCompilerSet_pressed()
@ -233,8 +236,14 @@ void CompilerSetOptionWidget::on_btnAddBlankCompilerSet_pressed()
void CompilerSetOptionWidget::on_btnAddCompilerSetByFolder_pressed()
{
QString folder = QFileDialog::getExistingDirectory(this, tr("Compiler Set Folder"));
int oldSize = pSettings->compilerSets().size();
pSettings->compilerSets().addSets(folder);
doLoad();
int newSize = pSettings->compilerSets().size();
if (oldSize == newSize) {
QMessageBox::warning(this,tr("Failed"),tr("Can't find any compiler."));
}
}
void CompilerSetOptionWidget::on_btnRenameCompilerSet_pressed()