diff options
author | Neil Hodgson <nyamatongwe@gmail.com> | 2015-02-22 10:12:28 +1100 |
---|---|---|
committer | Neil Hodgson <nyamatongwe@gmail.com> | 2015-02-22 10:12:28 +1100 |
commit | c1fbe6996a29bc05a5f8889c138f2bf3895de253 (patch) | |
tree | 9a7881f04ea1bd2cb0ea7e5eb5da7ab3040273ca /cocoa/ScintillaCocoa.mm | |
parent | 1fc21cb6664d3633602636cfc43ecbdb39b591a7 (diff) | |
download | scintilla-mirror-c1fbe6996a29bc05a5f8889c138f2bf3895de253.tar.gz |
Implement additional methods from the NSTextInputClient protocol so that more
features of the IME work. attributedSubstringForProposedRange:actualRange: and
characterIndexForPoint: now have full implementations.
This required using UTF-16 document indexes in many places as that is what
Cocoa wants. Tentative undo is used for the composition text instead of turning
off undo as that is safer and similar to IME code on other platforms.
Diffstat (limited to 'cocoa/ScintillaCocoa.mm')
-rw-r--r-- | cocoa/ScintillaCocoa.mm | 109 |
1 files changed, 92 insertions, 17 deletions
diff --git a/cocoa/ScintillaCocoa.mm b/cocoa/ScintillaCocoa.mm index f248f3bb0..ced7be3d6 100644 --- a/cocoa/ScintillaCocoa.mm +++ b/cocoa/ScintillaCocoa.mm @@ -2102,22 +2102,42 @@ bool ScintillaCocoa::KeyboardInput(NSEvent* event) int ScintillaCocoa::InsertText(NSString* input) { CFStringEncoding encoding = EncodingFromCharacterSet(IsUnicodeMode(), - vs.styles[STYLE_DEFAULT].characterSet); - CFRange rangeAll = {0, static_cast<CFIndex>([input length])}; - CFIndex usedLen = 0; - CFStringGetBytes((CFStringRef)input, rangeAll, encoding, '?', - false, NULL, 0, &usedLen); - - if (usedLen > 0) + vs.styles[STYLE_DEFAULT].characterSet); + std::string encoded = EncodedBytesString((CFStringRef)input, encoding); + + if (encoded.length() > 0) { - std::vector<UInt8> buffer(usedLen); + AddCharUTF((char*) encoded.c_str(), static_cast<unsigned int>(encoded.length()), false); + } + return static_cast<int>(encoded.length()); +} - CFStringGetBytes((CFStringRef)input, rangeAll, encoding, '?', - false, buffer.data(),usedLen, NULL); +//-------------------------------------------------------------------------------------------------- - AddCharUTF((char*) buffer.data(), static_cast<unsigned int>(usedLen), false); - } - return static_cast<int>(usedLen); +/** + * Convert from a range of characters to a range of bytes. + */ +NSRange ScintillaCocoa::PositionsFromCharacters(NSRange range) const +{ + long start = pdoc->GetRelativePositionUTF16(0, range.location); + if (start == INVALID_POSITION) + start = pdoc->Length(); + long end = pdoc->GetRelativePositionUTF16(start, range.length); + if (end == INVALID_POSITION) + end = pdoc->Length(); + return NSMakeRange(start, end - start); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Convert from a range of characters from a range of bytes. + */ +NSRange ScintillaCocoa::CharactersFromPositions(NSRange range) const +{ + const long start = pdoc->CountUTF16(0, range.location); + const long len = pdoc->CountUTF16(range.location, NSMaxRange(range)); + return NSMakeRange(start, len); } //-------------------------------------------------------------------------------------------------- @@ -2125,17 +2145,72 @@ int ScintillaCocoa::InsertText(NSString* input) /** * Used to ensure that only one selection is active for input composition as composition * does not support multi-typing. - * Also drop virtual space as that is not supported by composition. */ void ScintillaCocoa::SelectOnlyMainSelection() { - SelectionRange mainSel = sel.RangeMain(); - mainSel.ClearVirtualSpace(); - sel.SetSelection(mainSel); + sel.SetSelection(sel.RangeMain()); Redraw(); } //-------------------------------------------------------------------------------------------------- + +/** + * Convert virtual space before selection into real space. + */ +void ScintillaCocoa::ConvertSelectionVirtualSpace() +{ + FillVirtualSpace(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Erase all selected text and return whether the selection is now empty. + * The selection may not be empty if the selection contained protected text. + */ +bool ScintillaCocoa::ClearAllSelections() +{ + ClearSelection(true); + return sel.Empty(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Start composing for IME. + */ +void ScintillaCocoa::CompositionStart() +{ + if (!sel.Empty()) + { + NSLog(@"Selection not empty when starting composition"); + } + pdoc->TentativeStart(); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Commit the IME text. + */ +void ScintillaCocoa::CompositionCommit() +{ + pdoc->TentativeCommit(); + pdoc->decorations.SetCurrentIndicator(INDIC_IME); + pdoc->DecorationFillRange(0, 0, pdoc->Length()); +} + +//-------------------------------------------------------------------------------------------------- + +/** + * Remove the IME text. + */ +void ScintillaCocoa::CompositionUndo() +{ + pdoc->TentativeUndo(); +} + +//-------------------------------------------------------------------------------------------------- /** * When switching documents discard any incomplete character composition state as otherwise tries to * act on the new document. |