input method processing for line has selections and special areas
- fix: add mutex lock to prevent rare conditions when editor is modifying and the content is read
This commit is contained in:
parent
f8f5b7b0d8
commit
ffb87fe66c
|
@ -1181,8 +1181,10 @@ void Editor::addSyntaxIssues(int line, int startChar, int endChar, CompileIssueT
|
|||
}
|
||||
pError->startChar = start;
|
||||
pError->endChar = start + token.length();
|
||||
pError->col = charToColumn(line,pError->startChar);
|
||||
pError->endCol = charToColumn(line,pError->endChar);
|
||||
// pError->col = charToColumn(line,pError->startChar);
|
||||
// pError->endCol = charToColumn(line,pError->endChar);
|
||||
pError->col = pError->startChar;
|
||||
pError->endCol = pError->endChar;
|
||||
pError->hint = hint;
|
||||
pError->token = token;
|
||||
pError->issueType = errorType;
|
||||
|
|
|
@ -297,7 +297,7 @@ bool EditorList::getContentFromOpenedEditor(const QString &filename, QStringList
|
|||
Editor * e= getOpenedEditorByFilename(filename);
|
||||
if (!e)
|
||||
return false;
|
||||
buffer = e->lines()->contents();
|
||||
buffer = e->contents();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -4070,7 +4070,7 @@ void MainWindow::on_btnReplace_clicked()
|
|||
tr("Can't open file '%1' for replace!").arg(file->filename));
|
||||
return;
|
||||
}
|
||||
contents = editor->lines()->contents();
|
||||
contents = editor->contents();
|
||||
for (int i=file->results.count()-1;i>=0;i--) {
|
||||
const PSearchResultTreeItem& item = file->results[i];
|
||||
QString line = contents[item->line-1];
|
||||
|
|
|
@ -532,6 +532,12 @@ BufferCoord SynEdit::getMatchingBracketEx(BufferCoord APoint)
|
|||
return BufferCoord{0,0};
|
||||
}
|
||||
|
||||
QStringList SynEdit::contents()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
return lines()->contents();
|
||||
}
|
||||
|
||||
bool SynEdit::getPositionOfMouse(BufferCoord &aPos)
|
||||
{
|
||||
QPoint point = QCursor::pos();
|
||||
|
@ -891,7 +897,8 @@ void SynEdit::invalidateLine(int Line)
|
|||
QRect rcInval;
|
||||
if (mPainterLock >0)
|
||||
return;
|
||||
if (Line<1 || Line>mLines->count() || !isVisible())
|
||||
if (Line<1 || (Line>mLines->count() &&
|
||||
Line!=1) || !isVisible())
|
||||
return;
|
||||
|
||||
// invalidate text area of this line
|
||||
|
@ -4325,6 +4332,7 @@ void SynEdit::setSelTextPrimitiveEx(SynSelectionMode PasteMode, const QString &V
|
|||
|
||||
void SynEdit::setSelText(const QString &Value)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
mUndoList->BeginBlock();
|
||||
auto action = finally([this]{
|
||||
mUndoList->EndBlock();
|
||||
|
@ -4865,6 +4873,7 @@ void SynEdit::onCommandProcessed(SynEditorCommand , QChar , void *)
|
|||
|
||||
void SynEdit::ExecuteCommand(SynEditorCommand Command, QChar AChar, void *pData)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
incPaintLock();
|
||||
auto action=finally([this] {
|
||||
decPaintLock();
|
||||
|
@ -5597,9 +5606,8 @@ void SynEdit::mouseDoubleClickEvent(QMouseEvent *event)
|
|||
|
||||
void SynEdit::inputMethodEvent(QInputMethodEvent *event)
|
||||
{
|
||||
qDebug()<<"---";
|
||||
qDebug()<<event->replacementStart()<<":"<<event->replacementLength()<<" - "
|
||||
<< event->preeditString()<<" - "<<event->commitString();
|
||||
// qDebug()<<event->replacementStart()<<":"<<event->replacementLength()<<" - "
|
||||
// << event->preeditString()<<" - "<<event->commitString();
|
||||
|
||||
QString oldString = mInputPreeditString;
|
||||
mInputPreeditString = event->preeditString();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <QCursor>
|
||||
#include <QDateTime>
|
||||
#include <QFrame>
|
||||
#include <QMutex>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
@ -256,6 +257,8 @@ public:
|
|||
virtual BufferCoord getMatchingBracket();
|
||||
virtual BufferCoord getMatchingBracketEx(BufferCoord APoint);
|
||||
|
||||
QStringList contents();
|
||||
|
||||
bool getPositionOfMouse(BufferCoord& aPos);
|
||||
bool getLineOfMouse(int& line);
|
||||
bool pointToCharLine(const QPoint& point, BufferCoord& coord);
|
||||
|
@ -672,6 +675,8 @@ private:
|
|||
|
||||
QString mInputPreeditString;
|
||||
|
||||
QRecursiveMutex mMutex;
|
||||
|
||||
friend class SynEditTextPainter;
|
||||
|
||||
// QWidget interface
|
||||
|
|
|
@ -230,7 +230,8 @@ void SynEditStringList::setContents(const QStringList &text)
|
|||
QStringList SynEditStringList::contents()
|
||||
{
|
||||
QStringList Result;
|
||||
foreach (const PSynEditStringRec& line, mList) {
|
||||
SynEditStringRecList list = mList;
|
||||
foreach (const PSynEditStringRec& line, list) {
|
||||
Result.append(line->fString);
|
||||
}
|
||||
return Result;
|
||||
|
|
|
@ -301,6 +301,14 @@ void SynEditTextPainter::ComputeSelectionInfo()
|
|||
}
|
||||
} else
|
||||
bAnySelection = false;
|
||||
if (edit->mInputPreeditString.length()>0) {
|
||||
if (vStart.Line == edit->mCaretY && vStart.Char >=edit->mCaretX) {
|
||||
vStart.Char+=edit->mInputPreeditString.length();
|
||||
}
|
||||
if (vEnd.Line == edit->mCaretY && vEnd.Char >edit->mCaretX) {
|
||||
vEnd.Char+=edit->mInputPreeditString.length();
|
||||
}
|
||||
}
|
||||
// If there is any visible selection so far, then test if there is an
|
||||
// intersection with the area to be painted.
|
||||
if (bAnySelection) {
|
||||
|
@ -310,6 +318,20 @@ void SynEditTextPainter::ComputeSelectionInfo()
|
|||
// Transform the selection from text space into screen space
|
||||
vSelStart = edit->bufferToDisplayPos(vStart);
|
||||
vSelEnd = edit->bufferToDisplayPos(vEnd);
|
||||
if (edit->mInputPreeditString.length()
|
||||
&& vStart.Line == edit->mCaretY) {
|
||||
QString sLine = edit->lineText().left(edit->mCaretX-1)
|
||||
+ edit->mInputPreeditString
|
||||
+ edit->lineText().mid(edit->mCaretX-1);
|
||||
vSelStart.Column = edit->charToColumn(sLine,vStart.Char);
|
||||
}
|
||||
if (edit->mInputPreeditString.length()
|
||||
&& vEnd.Line == edit->mCaretY) {
|
||||
QString sLine = edit->lineText().left(edit->mCaretX-1)
|
||||
+ edit->mInputPreeditString
|
||||
+ edit->lineText().mid(edit->mCaretX-1);
|
||||
vSelEnd.Column = edit->charToColumn(sLine,vEnd.Char);
|
||||
}
|
||||
// In the column selection mode sort the begin and end of the selection,
|
||||
// this makes the painting code simpler.
|
||||
if (edit->mActiveSelectionMode == SynSelectionMode::smColumn && vSelStart.Column > vSelEnd.Column)
|
||||
|
@ -365,6 +387,8 @@ void SynEditTextPainter::PaintToken(const QString &Token, int TokenCols, int Col
|
|||
}
|
||||
startPaint = true;
|
||||
}
|
||||
if (tokenColLen+charCols > Last)
|
||||
break;
|
||||
//painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent()*edit->dpiFactor() , Token[i]);
|
||||
if (startPaint) {
|
||||
painter->drawText(nX,rcToken.bottom()-painter->fontMetrics().descent() , Token[i]);
|
||||
|
@ -372,8 +396,6 @@ void SynEditTextPainter::PaintToken(const QString &Token, int TokenCols, int Col
|
|||
}
|
||||
|
||||
tokenColLen += charCols;
|
||||
if (tokenColLen > Last)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,6 +734,7 @@ void SynEditTextPainter::PaintLines()
|
|||
int vLastChar;
|
||||
SynEditingAreaList areaList;
|
||||
PSynEditFoldRange foldRange;
|
||||
PSynHighlighterAttribute preeditAttr;
|
||||
int nFold;
|
||||
QString sFold;
|
||||
|
||||
|
@ -806,6 +829,10 @@ void SynEditTextPainter::PaintLines()
|
|||
nTokenColumnLen += edit->charColumns(SynLineBreakGlyph);
|
||||
}
|
||||
if (bComplexLine) {
|
||||
setDrawingColors(true);
|
||||
rcToken.setLeft(std::max(rcLine.left(), ColumnToXValue(nLineSelStart)));
|
||||
rcToken.setRight(std::min(rcLine.right(), ColumnToXValue(nLineSelEnd)));
|
||||
PaintToken(sToken, nTokenColumnLen, 0, nLineSelStart, nLineSelEnd,false);
|
||||
setDrawingColors(false);
|
||||
rcToken.setLeft(std::max(rcLine.left(), ColumnToXValue(FirstCol)));
|
||||
rcToken.setRight(std::min(rcLine.right(), ColumnToXValue(nLineSelStart)));
|
||||
|
@ -813,14 +840,20 @@ void SynEditTextPainter::PaintLines()
|
|||
rcToken.setLeft(std::max(rcLine.left(), ColumnToXValue(nLineSelEnd)));
|
||||
rcToken.setRight(std::min(rcLine.right(), ColumnToXValue(LastCol)));
|
||||
PaintToken(sToken, nTokenColumnLen, 0, nLineSelEnd, LastCol,true);
|
||||
setDrawingColors(true);
|
||||
rcToken.setLeft(std::max(rcLine.left(), ColumnToXValue(nLineSelStart)));
|
||||
rcToken.setRight(std::min(rcLine.right(), ColumnToXValue(nLineSelEnd)));
|
||||
PaintToken(sToken, nTokenColumnLen, 0, nLineSelStart, nLineSelEnd - 1,false);
|
||||
} else {
|
||||
setDrawingColors(bLineSelected);
|
||||
PaintToken(sToken, nTokenColumnLen, 0, FirstCol, LastCol,bLineSelected);
|
||||
}
|
||||
//Paint editingAreaBorders
|
||||
if (bCurrentLine && edit->mInputPreeditString.length()>0) {
|
||||
PSynEditingArea area = std::make_shared<SynEditingArea>();
|
||||
area->beginX = edit->charToColumn(sLine,edit->mCaretX);
|
||||
area->endX = edit->charToColumn(sLine,edit->mCaretX + edit->mInputPreeditString.length());
|
||||
area->type = SynEditingAreaType::eatUnderLine;
|
||||
area->color = colFG;
|
||||
areaList.append(area);
|
||||
PaintEditAreas(areaList);
|
||||
}
|
||||
} else {
|
||||
// Initialize highlighter with line text and range info. It is
|
||||
// necessary because we probably did not scan to the end of the last
|
||||
|
@ -876,6 +909,19 @@ void SynEditTextPainter::PaintLines()
|
|||
} else if (sToken == "}") {
|
||||
GetBraceColorAttr(edit->mHighlighter->getRangeState().braceLevel+1,attr);
|
||||
}
|
||||
if (bCurrentLine && edit->mInputPreeditString.length()>0) {
|
||||
int startPos = edit->mHighlighter->getTokenPos()+1;
|
||||
int endPos = edit->mHighlighter->getTokenPos() + sToken.length();
|
||||
qDebug()<<startPos<<":"<<endPos<<" - "+sToken+" - "<<edit->mCaretX<<":"<<edit->mCaretX+edit->mInputPreeditString.length();
|
||||
if (!(endPos < edit->mCaretX
|
||||
|| startPos >= edit->mCaretX+edit->mInputPreeditString.length())) {
|
||||
if (!preeditAttr) {
|
||||
preeditAttr = attr;
|
||||
} else {
|
||||
attr = preeditAttr;
|
||||
}
|
||||
}
|
||||
}
|
||||
AddHighlightToken(sToken, nTokenColumnsBefore - (vFirstChar - FirstCol),
|
||||
nTokenColumnLen, vLine,attr);
|
||||
}
|
||||
|
@ -921,13 +967,30 @@ void SynEditTextPainter::PaintLines()
|
|||
// of the invalid area with the correct colors.
|
||||
PaintHighlightToken(true);
|
||||
|
||||
|
||||
//Paint editingAreaBorders
|
||||
foreach (const PSynEditingArea& area, areaList) {
|
||||
if (bCurrentLine && edit->mInputPreeditString.length()>0) {
|
||||
if (area->beginX >= edit->mCaretX) {
|
||||
area->beginX+=edit->mInputPreeditString.length();
|
||||
}
|
||||
if (area->endX > edit->mCaretX) {
|
||||
area->endX+=edit->mInputPreeditString.length();
|
||||
}
|
||||
}
|
||||
area->beginX = edit->charToColumn(sLine, area->beginX);
|
||||
area->endX = edit->charToColumn(sLine,area->endX);
|
||||
}
|
||||
if (bCurrentLine && edit->mInputPreeditString.length()>0) {
|
||||
PSynEditingArea area = std::make_shared<SynEditingArea>();
|
||||
area->beginX = edit->mCaretX;
|
||||
area->endX = edit->mCaretX + edit->mInputPreeditString.length();
|
||||
area->beginX = edit->charToColumn(sLine, edit->mCaretX);
|
||||
area->endX = edit->charToColumn(sLine, edit->mCaretX + edit->mInputPreeditString.length());
|
||||
area->type = SynEditingAreaType::eatUnderLine;
|
||||
area->color = colFG;
|
||||
if (preeditAttr) {
|
||||
area->color = preeditAttr->foreground();
|
||||
} else {
|
||||
area->color = colFG;
|
||||
}
|
||||
areaList.append(area);
|
||||
}
|
||||
PaintEditAreas(areaList);
|
||||
|
@ -948,5 +1011,3 @@ void SynEditTextPainter::drawMark(PSynEditMark , int &, int )
|
|||
{
|
||||
//todo
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue