* work save: syntax error display in the editor
This commit is contained in:
parent
350be90c74
commit
1f403198e5
|
@ -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 \
|
||||
|
|
|
@ -15,6 +15,7 @@ struct CompileIssue {
|
|||
QString filename;
|
||||
int line;
|
||||
int column;
|
||||
int endColumn;
|
||||
QString description;
|
||||
CompileIssueType type;
|
||||
};
|
||||
|
|
|
@ -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()));
|
||||
});
|
||||
|
|
|
@ -56,6 +56,7 @@ protected:
|
|||
QString mOutputFile;
|
||||
int mErrorCount;
|
||||
int mWarningCount;
|
||||
PCompileIssue mLastIssue;
|
||||
|
||||
private:
|
||||
bool mStop;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue