diff --git a/RedPandaIDE/compiler/compiler.cpp b/RedPandaIDE/compiler/compiler.cpp index b3d0b022..b1aac093 100644 --- a/RedPandaIDE/compiler/compiler.cpp +++ b/RedPandaIDE/compiler/compiler.cpp @@ -56,11 +56,12 @@ QString Compiler::getFileNameFromOutputLine(QString &line) { } temp = line.mid(0,pos); line.remove(0,pos+1); - if (temp.compare("", Qt::CaseInsensitive)!=0 && !QFile(temp).exists()) { - continue; - } + line=line.trimmed(); +// if (temp.compare("", Qt::CaseInsensitive)!=0 && !QFile(temp).exists()) { +// continue; +// } - if (QFile(temp).fileName() == QLatin1String("ld.exe")) { // skip ld.exe + if (QFileInfo(temp).fileName() == QLatin1String("ld.exe")) { // skip ld.exe continue; } else { break; @@ -79,7 +80,8 @@ int Compiler::getLineNumberFromOutputLine(QString &line) } if (pos>=0) { result = line.mid(0,pos).toInt(); - line.remove(0,pos+1); + if (result > 0) + line.remove(0,pos+1); } return result; } @@ -138,7 +140,8 @@ void Compiler::processOutput(QString &line) line.remove(0,inFilePrefix.length()); issue->filename = getFileNameFromOutputLine(line); issue->line = getLineNumberFromOutputLine(line); - issue->column = getColunmnFromOutputLine(line); + if (issue->line > 0) + issue->column = getColunmnFromOutputLine(line); issue->type = getIssueTypeFromOutputLine(line); issue->description = inFilePrefix + issue->filename; emit compileIssue(issue); @@ -147,7 +150,8 @@ void Compiler::processOutput(QString &line) line.remove(0,fromPrefix.length()); issue->filename = getFileNameFromOutputLine(line); issue->line = getLineNumberFromOutputLine(line); - issue->column = getColunmnFromOutputLine(line); + if (issue->line > 0) + issue->column = getColunmnFromOutputLine(line); issue->type = getIssueTypeFromOutputLine(line); issue->description = " from " + issue->filename; emit compileIssue(issue); @@ -162,7 +166,8 @@ void Compiler::processOutput(QString &line) // assume regular main.cpp:line:col: message issue->filename = getFileNameFromOutputLine(line); issue->line = getLineNumberFromOutputLine(line); - issue->column = getColunmnFromOutputLine(line); + if (issue->line > 0) + issue->column = getColunmnFromOutputLine(line); issue->type = getIssueTypeFromOutputLine(line); issue->description = line.trimmed(); emit compileIssue(issue); @@ -302,10 +307,10 @@ void Compiler::runCommand(const QString &cmd, const QString &arguments, const Q process.setWorkingDirectory(workingDir); process.connect(&process, &QProcess::readyReadStandardError,[&process,this](){ - this->error(process.readAllStandardError()); + this->error(QString::fromLocal8Bit( process.readAllStandardError())); }); process.connect(&process, &QProcess::readyReadStandardOutput,[&process,this](){ - this->log(process.readAllStandardOutput()); + this->log(QString::fromLocal8Bit( process.readAllStandardOutput())); }); process.start(); if (!inputText.isEmpty()) diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 6f3598ce..93e2e29e 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -53,15 +53,23 @@ Editor::Editor(QWidget *parent, const QString& filename, mParentPageControl->addTab(this,QString()); updateCaption(); } + PSynHighlighter highlighter; if (!isNew) { loadFile(); - setHighlighter(highlighterManager.createHighlighter(mFilename)); + highlighter = highlighterManager.createHighlighter(mFilename); } else { if (mEncodingOption == ENCODING_AUTO_DETECT) mFileEncoding = ENCODING_ASCII; else mFileEncoding = mEncodingOption; - setHighlighter(highlighterManager.createCppHighlighter()); + highlighter=highlighterManager.createCppHighlighter(); + } + + if (highlighter) { + setHighlighter(highlighter); + setUseCodeFolding(true); + } else { + setUseCodeFolding(false); } //SynEditCppHighlighter highlighter; diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index d9e417f1..1ad0a71f 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -179,6 +179,12 @@ + + + 50 + false + + QAbstractItemView::NoEditTriggers diff --git a/RedPandaIDE/qsynedit/CodeFolding.cpp b/RedPandaIDE/qsynedit/CodeFolding.cpp index 4ad2cbb8..e74d03e5 100644 --- a/RedPandaIDE/qsynedit/CodeFolding.cpp +++ b/RedPandaIDE/qsynedit/CodeFolding.cpp @@ -85,9 +85,17 @@ SynEditFoldRanges::SynEditFoldRanges() } -PSynEditFoldRange SynEditFoldRanges::addByParts(PSynEditFoldRange aParent, PSynEditFoldRanges aAllFold, int aFromLine, PSynEditFoldRegion aFoldRegion, int aToLine) +PSynEditFoldRange SynEditFoldRanges::addByParts(PSynEditFoldRange aParent, + PSynEditFoldRanges aAllFold, + int aFromLine, + PSynEditFoldRegion aFoldRegion, + int aToLine) { PSynEditFoldRange range=std::make_shared(aParent,aAllFold, aFromLine,aFoldRegion,aToLine); + mRanges.append(range); + if (aAllFold && aAllFold.get()!=this) { + aAllFold->add(range); + } return range; } diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index 4ed4fea4..662ddcc5 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -125,6 +125,7 @@ SynEdit::SynEdit(QWidget *parent) : QAbstractScrollArea(parent) mContentImage = std::make_shared(clientWidth(),clientHeight(),QImage::Format_ARGB32); + mUseCodeFolding = true; m_blinkTimerId = 0; m_blinkStatus = 0; qDebug()<<"init SynEdit: 10"; @@ -1255,9 +1256,10 @@ void SynEdit::rescanForFoldRanges() void SynEdit::scanForFoldRanges(PSynEditFoldRanges TopFoldRanges) { + PSynEditFoldRanges parentFoldRanges = TopFoldRanges; // Recursively scan for folds (all types) for (int i= 0 ; i< mCodeFolding.foldRegions.count() ; i++ ) { - findSubFoldRange(TopFoldRanges, i,PSynEditFoldRange()); + findSubFoldRange(TopFoldRanges, i,parentFoldRanges,PSynEditFoldRange()); } } @@ -1291,11 +1293,9 @@ int SynEdit::lineHasChar(int Line, int startChar, QChar character, const QString return -1; } -void SynEdit::findSubFoldRange(PSynEditFoldRanges TopFoldRanges, int FoldIndex, PSynEditFoldRange Parent) +void SynEdit::findSubFoldRange(PSynEditFoldRanges TopFoldRanges, int FoldIndex,PSynEditFoldRanges& parentFoldRanges, PSynEditFoldRange Parent) { PSynEditFoldRange CollapsedFold; - PSynEditFoldRanges ParentFoldRanges; - ParentFoldRanges = TopFoldRanges; int Line = 0; QString CurLine; @@ -1330,13 +1330,13 @@ void SynEdit::findSubFoldRange(PSynEditFoldRanges TopFoldRanges, int FoldIndex, if (lineHasChar(Line,pos,mCodeFolding.foldRegions.get(FoldIndex)->closeSymbol, mCodeFolding.foldRegions.get(FoldIndex)->highlight)<0) { // Add it to the top list of folds - Parent = ParentFoldRanges->addByParts( + Parent = parentFoldRanges->addByParts( Parent, TopFoldRanges, Line + 1, mCodeFolding.foldRegions.get(FoldIndex), Line + 1); - ParentFoldRanges = Parent->subFoldRanges; + parentFoldRanges = Parent->subFoldRanges; // Skip until a newline break; @@ -1350,6 +1350,11 @@ void SynEdit::findSubFoldRange(PSynEditFoldRanges TopFoldRanges, int FoldIndex, if (Parent) { Parent->toLine = Line + 1; Parent = Parent->parent; + if (!Parent) { + parentFoldRanges = TopFoldRanges; + } else { + parentFoldRanges = Parent->subFoldRanges; + } } // Skip until a newline @@ -1562,6 +1567,19 @@ void SynEdit::doScrolled(int) invalidate(); } +bool SynEdit::useCodeFolding() const +{ + return mUseCodeFolding; +} + +void SynEdit::setUseCodeFolding(bool value) +{ + if (mUseCodeFolding!=value) { + mUseCodeFolding = value; + rescan(); + } +} + PSynHighlighter SynEdit::highlighter() const { return mHighlighter; @@ -1684,7 +1702,7 @@ void SynEdit::paintEvent(QPaintEvent *event) // Then the gutter area if it was (partly) invalidated. if (rcClip.left() < mGutterWidth) { rcDraw = rcClip; - rcDraw.setRight(mGutterWidth+1); + rcDraw.setRight(mGutterWidth); textPainter.paintGutter(rcDraw); } diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index 696c12db..f952b6a9 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -301,7 +301,7 @@ private: void rescanForFoldRanges(); void scanForFoldRanges(PSynEditFoldRanges TopFoldRanges); int lineHasChar(int Line, int startChar, QChar character, const QString& highlighterAttrName); - void findSubFoldRange(PSynEditFoldRanges TopFoldRanges,int FoldIndex, PSynEditFoldRange Parent); + void findSubFoldRange(PSynEditFoldRanges TopFoldRanges,int FoldIndex,PSynEditFoldRanges& parentFoldRanges, PSynEditFoldRange Parent); PSynEditFoldRange collapsedFoldStartAtLine(int Line); void setSelTextPrimitiveEx(SynSelectionMode PasteMode, const QString& Value, bool AddToUndoList); @@ -462,6 +462,9 @@ bool event(QEvent *event) override; PSynHighlighter highlighter() const; void setHighlighter(const PSynHighlighter &highlighter); +bool useCodeFolding() const; +void setUseCodeFolding(bool value); + protected: void focusInEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override; diff --git a/RedPandaIDE/qsynedit/TextPainter.cpp b/RedPandaIDE/qsynedit/TextPainter.cpp index c71ceced..2dbb5cbd 100644 --- a/RedPandaIDE/qsynedit/TextPainter.cpp +++ b/RedPandaIDE/qsynedit/TextPainter.cpp @@ -130,7 +130,7 @@ void SynEditTextPainter::paintGutter(const QRect& clip) QRectF textRect; textRect = painter->boundingRect(textRect, Qt::AlignLeft,s); painter->drawText( - (edit->mGutterWidth - edit->mGutter.rightOffset() - 2) - textRect.width(), + (edit->mGutterWidth - edit->mGutter.rightOffset() - 2) - textRect.width(), rcLine.bottom() + ((edit->mTextHeight - int(textRect.height())) / 2 - painter->fontMetrics().descent()), s ); @@ -138,71 +138,71 @@ void SynEditTextPainter::paintGutter(const QRect& clip) } // Draw the folding lines and squares -// if (edit->mUseCodeFolding) { -// for (cRow = aFirstRow; cRow<=aLastRow; cRow++) { -// vLine = edit->rowToLine(cRow); -// if ((vLine > edit->mLines->count()) && (edit->mLines->count() != 0)) -// break; + if (edit->mUseCodeFolding) { + for (cRow = aFirstRow; cRow<=aLastRow; cRow++) { + vLine = edit->rowToLine(cRow); + if ((vLine > edit->mLines->count()) && (edit->mLines->count() != 0)) + break; -// // Form a rectangle for the square the user can click on -// //rcFold.Left := Gutter.RealGutterWidth(CharWidth) - Gutter.RightOffset; -// rcFold.setLeft(edit->mGutterWidth - edit->mGutter.rightOffset()); -// rcFold.setRight(rcFold.left() + edit->mGutter.rightOffset() - 4); -// rcFold.setTop((cRow - edit->mTopLine) * edit->mTextHeight); -// rcFold.setBottom(rcFold.top() + edit->mTextHeight); + // Form a rectangle for the square the user can click on + //rcFold.Left := Gutter.RealGutterWidth(CharWidth) - Gutter.RightOffset; + rcFold.setLeft(edit->mGutterWidth - edit->mGutter.rightOffset()); + rcFold.setRight(rcFold.left() + edit->mGutter.rightOffset() - 4); + rcFold.setTop((cRow - edit->mTopLine) * edit->mTextHeight); + rcFold.setBottom(rcFold.top() + edit->mTextHeight); -// painter->setPen(edit->mCodeFolding.folderBarLinesColor); + painter->setPen(edit->mCodeFolding.folderBarLinesColor); -// // Need to paint a line? -// if (edit->foldAroundLine(vLine)) { -// x = rcFold.left() + (rcFold.width() / 2); -// painter->drawLine(x,rcFold.top(), x, rcFold.bottom()); -// } + // Need to paint a line? + if (edit->foldAroundLine(vLine)) { + x = rcFold.left() + (rcFold.width() / 2); + painter->drawLine(x,rcFold.top(), x, rcFold.bottom()); + } -// // Need to paint a line end? -// if (edit->foldEndAtLine(vLine)) { -// x = rcFold.left() + (rcFold.width() / 2); -// painter->drawLine(x,rcFold.top(), x, rcFold.top() + rcFold.height() / 2); -// painter->drawLine(x, -// rcFold.top() + rcFold.height() / 2, -// rcFold.right() - 2 , -// rcFold.top() + rcFold.height() / 2); -// } -// // Any fold ranges beginning on this line? -// PSynEditFoldRange FoldRange = edit->foldStartAtLine(vLine); -// if (FoldRange) { -// // Draw the bottom part of a line -// if (!FoldRange->collapsed) { -// x = rcFold.left() + (rcFold.width() / 2); -// painter->drawLine(x, rcFold.top() + rcFold.height() / 2, -// x, rcFold.bottom()); -// } + // Need to paint a line end? + if (edit->foldEndAtLine(vLine)) { + x = rcFold.left() + (rcFold.width() / 2); + painter->drawLine(x,rcFold.top(), x, rcFold.top() + rcFold.height() / 2); + painter->drawLine(x, + rcFold.top() + rcFold.height() / 2, + rcFold.right() - 2 , + rcFold.top() + rcFold.height() / 2); + } + // Any fold ranges beginning on this line? + PSynEditFoldRange FoldRange = edit->foldStartAtLine(vLine); + if (FoldRange) { + // Draw the bottom part of a line + if (!FoldRange->collapsed) { + x = rcFold.left() + (rcFold.width() / 2); + painter->drawLine(x, rcFold.top() + rcFold.height() / 2, + x, rcFold.bottom()); + } -// // make a square rect -// inflateRect(rcFold,-2, 0); -// rcFold.setTop( -// rcFold.top() + ((edit->mTextHeight - rcFold.width()) / 2)); -// rcFold.setBottom(rcFold.top() + rcFold.width()); + // make a square rect + inflateRect(rcFold,-2, 0); + rcFold.setTop( + rcFold.top() + ((edit->mTextHeight - rcFold.width()) / 2)); + rcFold.setBottom(rcFold.top() + rcFold.width()); -// // Paint the square the user can click on -// painter->setBrush(edit->mGutter.color()); -// painter->setPen(edit->mCodeFolding.folderBarLinesColor); -// painter->drawRect(rcFold); + // Paint the square the user can click on + painter->setBrush(edit->mGutter.color()); + painter->setPen(edit->mCodeFolding.folderBarLinesColor); + painter->drawRect(rcFold); -// // Paint minus sign -// painter->drawLine( -// rcFold.left() + 2, rcFold.top() + (rcFold.height() / 2 ), -// rcFold.right() - 2, rcFold.top() + (rcFold.height() / 2 )); -// // Paint vertical line of plus sign -// if (FoldRange->collapsed) { -// x = rcFold.left() + (rcFold.width() / 2); -// painter->drawLine(x, rcFold.top() + 2, -// x, rcFold.bottom() + 2); -// } -// } -// } -// } + // Paint minus sign + painter->drawLine( + rcFold.left() + 2, rcFold.top() + (rcFold.height() / 2 ), + rcFold.right() - 2, rcFold.top() + (rcFold.height() / 2 )); + // Paint vertical line of plus sign + if (FoldRange->collapsed) { + x = rcFold.left() + (rcFold.width() / 2); + painter->drawLine(x, rcFold.top() + 2, + x, rcFold.bottom() + 2); + } + } + } + } // // the gutter separator if visible // if (edit->mGutter.borderStyle <> gbsNone) and (AClip.Right >= fGutterWidth - 2) then @@ -351,6 +351,7 @@ void SynEditTextPainter::PaintToken(const QString &Token, int TokenCols, int Col int nX; if (Last >= First && rcToken.right() > rcToken.left()) { +// qDebug()<<"Paint Token"<foreground(); Background = p_Attri->background(); @@ -861,7 +864,7 @@ void SynEditTextPainter::PaintLines() throw BaseError(SynEdit::tr("The highlighter seems to be in an infinite loop")); } nTokenColumnsBefore = edit->charToColumn(vLine,edit->mHighlighter->getTokenPos()+1)-1; - nTokenColumnLen = edit->stringColumns(sToken, nTokenColumnsBefore-1); + nTokenColumnLen = edit->stringColumns(sToken, nTokenColumnsBefore); if (nTokenColumnsBefore + nTokenColumnLen >= vFirstChar) { if (nTokenColumnsBefore + nTokenColumnLen >= vLastChar) { if (nTokenColumnsBefore >= vLastChar) diff --git a/RedPandaIDE/widgets/issuestable.cpp b/RedPandaIDE/widgets/issuestable.cpp index 47927230..75044d2d 100644 --- a/RedPandaIDE/widgets/issuestable.cpp +++ b/RedPandaIDE/widgets/issuestable.cpp @@ -11,7 +11,6 @@ IssuesTable::IssuesTable(QWidget *parent): this->setColumnWidth(0,200); this->setColumnWidth(1,45); this->setColumnWidth(2,45); - } IssuesModel *IssuesTable::issuesModel() @@ -138,6 +137,20 @@ QVariant IssuesModel::data(const QModelIndex &index, int role) const default: return QVariant(); } + case Qt::FontRole: { + QFont newFont=((IssuesTable *)parent())->font(); + switch(issue->type) { + case CompileIssueType::Error: + case CompileIssueType::Warning: + { + newFont.setBold(true); + break; + } + default: + newFont.setBold(issue->line == 0); + } + return newFont; + } default: return QVariant(); }