add underline to indicate current ime input

This commit is contained in:
royqh1979@gmail.com 2021-10-05 00:42:35 +08:00
parent 3ed5701621
commit f8f5b7b0d8
5 changed files with 82 additions and 60 deletions

View File

@ -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;

View File

@ -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,

View File

@ -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"<<mCaretX<<mCaretY;
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);
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()<<event->replacementStart()<<":"<<event->replacementLength()<<" - "
<< event->preeditString()<<" - "<<event->commitString();
QString oldString = mInputPreeditString;
mInputPreeditString = event->preeditString();
if (oldString!=mInputPreeditString) {
invalidateLine(mCaretY);
}
QString s = event->commitString();
if (!s.isEmpty()) {
commandProcessor(SynEditorCommand::ecImeStr,QChar(),&s);

View File

@ -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

View File

@ -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<SynEditingArea>();
area->beginX = edit->mCaretX;
area->endX = edit->mCaretX + edit->mInputPreeditString.length();
area->type = SynEditingAreaType::eatUnderLine;
area->color = colFG;
areaList.append(area);
}
PaintEditAreas(areaList);
}