diff options
| author | johnsonj <unknown> | 2016-01-07 12:22:28 +1100 | 
|---|---|---|
| committer | johnsonj <unknown> | 2016-01-07 12:22:28 +1100 | 
| commit | 8a7ec32ee869c462536b5ffc80c482689f7d5cfd (patch) | |
| tree | 6a68fed40c2fad14ccb97c0ec530e13b84cc95bd /qt/ScintillaEditBase/ScintillaEditBase.cpp | |
| parent | 9fed0af96ce3f5bb1f9a3259497bd66602afa339 (diff) | |
| download | scintilla-mirror-8a7ec32ee869c462536b5ffc80c482689f7d5cfd.tar.gz | |
Factored out mapping IME state to indicators and finding caret position.
Diffstat (limited to 'qt/ScintillaEditBase/ScintillaEditBase.cpp')
| -rw-r--r-- | qt/ScintillaEditBase/ScintillaEditBase.cpp | 121 | 
1 files changed, 66 insertions, 55 deletions
| diff --git a/qt/ScintillaEditBase/ScintillaEditBase.cpp b/qt/ScintillaEditBase/ScintillaEditBase.cpp index 13401fedf..fd91e395d 100644 --- a/qt/ScintillaEditBase/ScintillaEditBase.cpp +++ b/qt/ScintillaEditBase/ScintillaEditBase.cpp @@ -438,6 +438,68 @@ void ScintillaEditBase::DrawImeIndicator(int indicator, int len)  	}  } +static int GetImeCaretPos(QInputMethodEvent *event) +{ +	foreach (QInputMethodEvent::Attribute attr, event->attributes()) { +		if (attr.type == QInputMethodEvent::Cursor) +			return attr.start; +	} +	return 0; +} + +static std::vector<int> MapImeIndicators(QInputMethodEvent *event, bool preeditNotChanged) +{ +#ifndef Q_OS_LINUX +	Q_UNUSED(preeditNotChanged) +#endif +	const QString preeditStr = event->preeditString(); +	std::vector<int> imeIndicator(preeditStr.length(), SC_INDICATOR_UNKNOWN); +#ifdef Q_OS_LINUX +	const int imeCaretPos = GetImeCaretPos(event); +#endif + +	foreach (QInputMethodEvent::Attribute attr, event->attributes()) { +		if (attr.type == QInputMethodEvent::TextFormat) { +			QTextFormat format = attr.value.value<QTextFormat>(); +			QTextCharFormat charFormat = format.toCharFormat(); + +			int indicator = SC_INDICATOR_UNKNOWN; +			switch (charFormat.underlineStyle()) { +				case QTextCharFormat::NoUnderline: +					indicator = SC_INDICATOR_TARGET; //target input +					break; +				case QTextCharFormat::SingleUnderline: +				case QTextCharFormat::DashUnderline: +					indicator = SC_INDICATOR_INPUT; //normal input +					break; +				case QTextCharFormat::DotLine: +				case QTextCharFormat::DashDotLine: +				case QTextCharFormat::WaveUnderline: +				case QTextCharFormat::SpellCheckUnderline: +					indicator = SC_INDICATOR_CONVERTED; +					break; + +				default: +					indicator = SC_INDICATOR_UNKNOWN; +			} +#ifdef Q_OS_LINUX +			// ibus-qt has a bug to return only one underline style. +			// Q_OS_LINUX blocks are temporary work around to cope with it. +			if ((attr.length > 0) && (attr.start == imeCaretPos)) { +				indicator = SC_INDICATOR_TARGET; +				if ((imeCaretPos == 0) && (preeditNotChanged)) { // moved by an arrow key. +					indicator = SC_INDICATOR_INPUT; +				} +			} +#endif +			for (int i = attr.start; i < attr.start+attr.length; i++) { +				imeIndicator[i] = indicator; +			} +		} +	} +	return imeIndicator; +} +  void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)  {  	// Copy & paste by johnsonj with a lot of helps of Neil @@ -482,55 +544,11 @@ void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)  		sqt->pdoc->TentativeStart(); // TentativeActive() from now on. -		// Mark segments and get ime caret position. -		unsigned int imeCaretPos = 0; -		unsigned int imeIndicator[MAXLENINPUTIME] = {0}; -#ifdef Q_OS_LINUX -		// ibus-qt has a bug to return only one underline style. -		// Q_OS_LINUX blocks are temporary work around to cope with it. -		unsigned int attrSegment = 0; -#endif - -		foreach (QInputMethodEvent::Attribute attr, event->attributes()) { -			if (attr.type == QInputMethodEvent::TextFormat) { -				QTextFormat format = attr.value.value<QTextFormat>(); -				QTextCharFormat charFormat = format.toCharFormat(); - -				unsigned int indicator = SC_INDICATOR_UNKNOWN; -				switch (charFormat.underlineStyle()) { -					case QTextCharFormat::NoUnderline: -						indicator = SC_INDICATOR_TARGET; //target input -						break; -					case QTextCharFormat::SingleUnderline: -					case QTextCharFormat::DashUnderline: -						indicator = SC_INDICATOR_INPUT; //normal input -						break; -					case QTextCharFormat::DotLine: -					case QTextCharFormat::DashDotLine: -					case QTextCharFormat::WaveUnderline: -					case QTextCharFormat::SpellCheckUnderline: -						indicator = SC_INDICATOR_CONVERTED; -						break; - -					default: -						indicator = SC_INDICATOR_UNKNOWN; -				} - -#ifdef Q_OS_LINUX -				attrSegment++; -				indicator = attr.start; -#endif -				for (int i = attr.start; i < attr.start+attr.length; i++) { -					imeIndicator[i] = indicator; -				} -			} else if (attr.type == QInputMethodEvent::Cursor) { -				imeCaretPos = attr.start; -			} -		} +		std::vector<int> imeIndicator = MapImeIndicators(event, preeditString == preeditStr);  #ifdef Q_OS_LINUX -		const bool targetInput = (attrSegment > 1) || ((imeCaretPos == 0) && (preeditStr != preeditString));  		preeditString = preeditStr;  #endif +  		// Display preedit characters one by one.  		int imeCharPos[MAXLENINPUTIME] = {0};  		int numBytes = 0; @@ -549,21 +567,14 @@ void ScintillaEditBase::inputMethodEvent(QInputMethodEvent *event)  			sqt->AddCharUTF(oneChar.data(), oneCharLen); -#ifdef Q_OS_LINUX -			// Segment marked with imeCaretPos is for target input. -			if ((imeIndicator[i] == imeCaretPos) && (targetInput)) { -				DrawImeIndicator(SC_INDICATOR_TARGET, oneCharLen); -			} else { -				DrawImeIndicator(SC_INDICATOR_INPUT, oneCharLen); -			} -#else  			DrawImeIndicator(imeIndicator[i], oneCharLen); -#endif +  			i += ucWidth;  		}  		sqt->recordingMacro = recording;  		// Move IME carets. +		int imeCaretPos = GetImeCaretPos(event);  		MoveImeCarets(- imeCharPos[preeditStrLen] + imeCharPos[imeCaretPos]);  		if (IsHangul(preeditStr.at(0))) { | 
