diff --git a/NEWS.md b/NEWS.md index d55e764c..28bf5893 100644 --- a/NEWS.md +++ b/NEWS.md @@ -19,6 +19,7 @@ Version 0.6.0 - fix: code fold parsing not correct - enhancement: support #include_next (and clang libc++) - fix: hide popup windows when the editor is closed + - enhancement: show pinyin when input chinese characters Version 0.5.0 - enhancement: support C++ using type alias; diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index d011acaa..84d10579 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -1020,49 +1020,40 @@ void Editor::mouseReleaseEvent(QMouseEvent *event) void Editor::inputMethodEvent(QInputMethodEvent *event) { - bool handled = false; - auto action = finally([this,&handled,event](){ - if (!handled) - SynEdit::inputMethodEvent(event); - }); + SynEdit::inputMethodEvent(event); + QString s = event->commitString(); + if (s.isEmpty()) + return; if (pMainWindow->completionPopup()->isVisible()) { - if (onCompletionInputMethod(event)) { - handled = true; - return; - } + onCompletionInputMethod(event); + return; } else { - QString s = event->commitString(); - if (!s.isEmpty()) { - mLastIdCharPressed+=s.length(); - if (pSettings->codeCompletion().enabled() - && pSettings->codeCompletion().showCompletionWhileInput() ) { - if (mLastIdCharPressed>=1) { - QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY()); - if (!lastWord.isEmpty()) { - if (CppTypeKeywords.contains(lastWord)) { - return; - } - PStatement statement = mParser->findStatementOf( - mFilename, - lastWord, - caretY()); - StatementKind kind = mParser->getKindOfStatement(statement); - if (kind == StatementKind::skClass - || kind == StatementKind::skEnumClassType - || kind == StatementKind::skEnumType - || kind == StatementKind::skTypedef) { - //last word is a typedef/class/struct, this is a var or param define, and dont show suggestion - // if devEditor.UseTabnine then - // ShowTabnineCompletion; - return; - } + mLastIdCharPressed+=s.length(); + if (pSettings->codeCompletion().enabled() + && pSettings->codeCompletion().showCompletionWhileInput() ) { + if (mLastIdCharPressed>=1) { + QString lastWord = getPreviousWordAtPositionForSuggestion(caretXY()); + if (!lastWord.isEmpty()) { + if (CppTypeKeywords.contains(lastWord)) { + return; + } + PStatement statement = mParser->findStatementOf( + mFilename, + lastWord, + caretY()); + StatementKind kind = mParser->getKindOfStatement(statement); + if (kind == StatementKind::skClass + || kind == StatementKind::skEnumClassType + || kind == StatementKind::skEnumType + || kind == StatementKind::skTypedef) { + //last word is a typedef/class/struct, this is a var or param define, and dont show suggestion + // if devEditor.UseTabnine then + // ShowTabnineCompletion; + return; } - setSelText(s); - showCompletion(false); - handled = true; - return; } - + showCompletion(false); + return; } } } @@ -2424,7 +2415,6 @@ bool Editor::onCompletionInputMethod(QInputMethodEvent *event) return processed; QString s=event->commitString(); if (!s.isEmpty()) { - setSelText(s); BufferCoord pBeginPos,pEndPos; QString phrase = getWordAtPosition(this,caretXY(), pBeginPos,pEndPos, diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index c24ddfda..7e0b5ebc 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -2137,6 +2137,24 @@ bool SynEdit::canDoBlockIndent() return true; } +QRect SynEdit::calculateCaretRect() +{ + DisplayCoord coord = displayXY(); + if (!mInputPreeditString.isEmpty()) { + QString sLine = lineText().left(mCaretX-1) + + mInputPreeditString + + lineText().mid(mCaretX-1); + coord.Column = charToColumn(sLine,mCaretX+mInputPreeditString.length()); + } + QPoint caretPos = rowColumnToPixels(coord); + int caretWidth=mCharWidth; + if (mCaretY <= mLines->count() && mCaretX <= mLines->getString(mCaretY-1).length()) { + caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth; + } + return QRect(caretPos.x(),caretPos.y(),caretWidth, + mTextHeight); +} + void SynEdit::clearAreaList(SynEditingAreaList areaList) { areaList.clear(); @@ -2687,16 +2705,7 @@ void SynEdit::updateScrollbars() void SynEdit::updateCaret() { mStateFlags.setFlag(SynStateFlag::sfCaretChanged,false); - DisplayCoord coord = displayXY(); - QPoint caretPos = rowColumnToPixels(coord); - int caretWidth=mCharWidth; - //qDebug()<<"caret"<count() && mCaretX <= mLines->getString(mCaretY-1).length()) { - caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth; - } - QRect rcCaret(caretPos.x(),caretPos.y(),caretWidth, - mTextHeight); - invalidateRect(rcCaret); + invalidateRect(calculateCaretRect()); } void SynEdit::recalcCharExtent() @@ -5325,14 +5334,7 @@ void SynEdit::paintEvent(QPaintEvent *event) QPainter painter(viewport()); //Get the invalidated rect. QRect rcClip = event->rect(); - DisplayCoord coord = displayXY(); - QPoint caretPos = rowColumnToPixels(coord); - int caretWidth=mCharWidth; - if (mCaretY <= mLines->count() && mCaretX <= mLines->getString(mCaretY-1).length()) { - caretWidth = charColumns(mLines->getString(mCaretY-1)[mCaretX-1])*mCharWidth; - } - QRect rcCaret(caretPos.x(),caretPos.y(),caretWidth, - mTextHeight); + QRect rcCaret = calculateCaretRect(); if (rcCaret == rcClip) { // only update caret @@ -5595,6 +5597,15 @@ void SynEdit::mouseDoubleClickEvent(QMouseEvent *event) void SynEdit::inputMethodEvent(QInputMethodEvent *event) { + qDebug()<<"---"; + qDebug()<replacementStart()<<":"<replacementLength()<<" - " + << event->preeditString()<<" - "<commitString(); + + QString oldString = mInputPreeditString; + mInputPreeditString = event->preeditString(); + if (oldString!=mInputPreeditString) { + invalidateLine(mCaretY); + } QString s = event->commitString(); if (!s.isEmpty()) { commandProcessor(SynEditorCommand::ecImeStr,QChar(),&s); diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index 0f070eca..e303eb2c 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -505,6 +505,8 @@ private: BufferCoord getPreviousLeftBracket(int x,int y); bool canDoBlockIndent(); + QRect calculateCaretRect(); + //Commands void doDeleteLastChar(); void doDeleteCurrentChar(); @@ -668,6 +670,8 @@ private: QCursor mDefaultCursor; + QString mInputPreeditString; + friend class SynEditTextPainter; // QWidget interface diff --git a/RedPandaIDE/qsynedit/TextPainter.cpp b/RedPandaIDE/qsynedit/TextPainter.cpp index 5310b1f6..ea177d2f 100644 --- a/RedPandaIDE/qsynedit/TextPainter.cpp +++ b/RedPandaIDE/qsynedit/TextPainter.cpp @@ -731,6 +731,10 @@ void SynEditTextPainter::PaintLines() sLine = edit->mLines->getString(vLine - 1); // determine whether will be painted with ActiveLineColor bCurrentLine = (edit->mCaretY == vLine); + if (bCurrentLine && !edit->mInputPreeditString.isEmpty()) { + sLine = sLine.left(edit->mCaretX-1) + edit->mInputPreeditString + + sLine.mid(edit->mCaretX-1); + } // Initialize the text and background colors, maybe the line should // use special values for them. colFG = edit->palette().color(QPalette::Text); @@ -792,7 +796,11 @@ void SynEditTextPainter::PaintLines() rcToken = rcLine; if (!edit->mHighlighter || !edit->mHighlighter->enabled()) { sToken = sLine; - nTokenColumnLen = edit->mLines->lineColumns(vLine-1); + if (bCurrentLine) { + nTokenColumnLen = edit->stringColumns(sLine,0); + } else { + nTokenColumnLen = edit->mLines->lineColumns(vLine-1); + } if (edit->mOptions.testFlag(eoShowSpecialChars) && (!bLineSelected) && (!bSpecialLine) && (nTokenColumnLen < vLastChar)) { sToken = sToken + SynLineBreakGlyph; nTokenColumnLen += edit->charColumns(SynLineBreakGlyph); @@ -845,7 +853,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; + nTokenColumnsBefore = edit->charToColumn(sLine,edit->mHighlighter->getTokenPos()+1)-1; nTokenColumnLen = edit->stringColumns(sToken, nTokenColumnsBefore); if (nTokenColumnsBefore + nTokenColumnLen >= vFirstChar) { if (nTokenColumnsBefore + nTokenColumnLen >= vLastChar) { @@ -914,6 +922,14 @@ void SynEditTextPainter::PaintLines() PaintHighlightToken(true); //Paint editingAreaBorders + if (bCurrentLine && edit->mInputPreeditString.length()>0) { + PSynEditingArea area = std::make_shared(); + area->beginX = edit->mCaretX; + area->endX = edit->mCaretX + edit->mInputPreeditString.length(); + area->type = SynEditingAreaType::eatUnderLine; + area->color = colFG; + areaList.append(area); + } PaintEditAreas(areaList); }