macOS: Restructure QNSView complex text implementation
For better overview of the flow and functionality of the NSTextInputClient protocol. Pick-to: 6.2 Change-Id: I8658405c7ff4ae762bfe3e4c11f9a157ae2b9a09 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
b601eb9c2d
commit
42573d9496
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -39,61 +39,9 @@
|
|||||||
|
|
||||||
// This file is included from qnsview.mm, and only used to organize the code
|
// This file is included from qnsview.mm, and only used to organize the code
|
||||||
|
|
||||||
@implementation QNSView (ComplexTextAPI)
|
|
||||||
|
|
||||||
- (void)cancelComposingText
|
|
||||||
{
|
|
||||||
if (m_composingText.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
qCDebug(lcQpaKeys) << "Canceling composition" << m_composingText
|
|
||||||
<< "for focus object" << m_composingFocusObject;
|
|
||||||
|
|
||||||
if (queryInputMethod(m_composingFocusObject)) {
|
|
||||||
QInputMethodEvent e;
|
|
||||||
QCoreApplication::sendEvent(m_composingFocusObject, &e);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_composingText.clear();
|
|
||||||
m_composingFocusObject = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)unmarkText
|
|
||||||
{
|
|
||||||
// FIXME: Match cancelComposingText in early exit and focus object handling
|
|
||||||
|
|
||||||
qCDebug(lcQpaKeys) << "Unmarking" << m_composingText
|
|
||||||
<< "for focus object" << m_composingFocusObject;
|
|
||||||
|
|
||||||
if (!m_composingText.isEmpty()) {
|
|
||||||
QObject *focusObject = m_platformWindow->window()->focusObject();
|
|
||||||
if (queryInputMethod(focusObject)) {
|
|
||||||
QInputMethodEvent e;
|
|
||||||
e.setCommitString(m_composingText);
|
|
||||||
QCoreApplication::sendEvent(focusObject, &e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_composingText.clear();
|
|
||||||
m_composingFocusObject = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation QNSView (ComplexText)
|
@implementation QNSView (ComplexText)
|
||||||
|
|
||||||
- (void)insertNewline:(id)sender
|
// ------------- Text insertion -------------
|
||||||
{
|
|
||||||
Q_UNUSED(sender);
|
|
||||||
qCDebug(lcQpaKeys) << "Inserting newline";
|
|
||||||
m_resendKeyEvent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)doCommandBySelector:(SEL)aSelector
|
|
||||||
{
|
|
||||||
qCDebug(lcQpaKeys) << "Trying to perform command" << aSelector;
|
|
||||||
[self tryToPerform:aSelector with:self];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
|
- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange
|
||||||
{
|
{
|
||||||
@ -121,6 +69,15 @@
|
|||||||
m_composingFocusObject = nullptr;
|
m_composingFocusObject = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)insertNewline:(id)sender
|
||||||
|
{
|
||||||
|
Q_UNUSED(sender);
|
||||||
|
qCDebug(lcQpaKeys) << "Inserting newline";
|
||||||
|
m_resendKeyEvent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------- Text composition -------------
|
||||||
|
|
||||||
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
|
- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange
|
||||||
{
|
{
|
||||||
qCDebug(lcQpaKeys).nospace() << "Marking \"" << aString << "\""
|
qCDebug(lcQpaKeys).nospace() << "Marking \"" << aString << "\""
|
||||||
@ -182,9 +139,94 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSArray<NSString *> *)validAttributesForMarkedText
|
||||||
|
{
|
||||||
|
if (!m_platformWindow)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
if (m_platformWindow->window() != QGuiApplication::focusWindow())
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
if (queryInputMethod(m_platformWindow->window()->focusObject()))
|
||||||
|
return @[NSUnderlineColorAttributeName, NSUnderlineStyleAttributeName];
|
||||||
|
else
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)hasMarkedText
|
- (BOOL)hasMarkedText
|
||||||
{
|
{
|
||||||
return (m_composingText.isEmpty() ? NO: YES);
|
return !m_composingText.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSRange)markedRange
|
||||||
|
{
|
||||||
|
NSRange range;
|
||||||
|
if (!m_composingText.isEmpty()) {
|
||||||
|
range.location = 0;
|
||||||
|
range.length = m_composingText.length();
|
||||||
|
} else {
|
||||||
|
range.location = NSNotFound;
|
||||||
|
range.length = 0;
|
||||||
|
}
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)unmarkText
|
||||||
|
{
|
||||||
|
// FIXME: Match cancelComposingText in early exit and focus object handling
|
||||||
|
|
||||||
|
qCDebug(lcQpaKeys) << "Unmarking" << m_composingText
|
||||||
|
<< "for focus object" << m_composingFocusObject;
|
||||||
|
|
||||||
|
if (!m_composingText.isEmpty()) {
|
||||||
|
QObject *focusObject = m_platformWindow->window()->focusObject();
|
||||||
|
if (queryInputMethod(focusObject)) {
|
||||||
|
QInputMethodEvent e;
|
||||||
|
e.setCommitString(m_composingText);
|
||||||
|
QCoreApplication::sendEvent(focusObject, &e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_composingText.clear();
|
||||||
|
m_composingFocusObject = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cancelComposingText
|
||||||
|
{
|
||||||
|
if (m_composingText.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
qCDebug(lcQpaKeys) << "Canceling composition" << m_composingText
|
||||||
|
<< "for focus object" << m_composingFocusObject;
|
||||||
|
|
||||||
|
if (queryInputMethod(m_composingFocusObject)) {
|
||||||
|
QInputMethodEvent e;
|
||||||
|
QCoreApplication::sendEvent(m_composingFocusObject, &e);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_composingText.clear();
|
||||||
|
m_composingFocusObject = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------- Key binding command handling -------------
|
||||||
|
|
||||||
|
- (void)doCommandBySelector:(SEL)aSelector
|
||||||
|
{
|
||||||
|
qCDebug(lcQpaKeys) << "Trying to perform command" << aSelector;
|
||||||
|
[self tryToPerform:aSelector with:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------- Various text properties -------------
|
||||||
|
|
||||||
|
- (NSRange)selectedRange
|
||||||
|
{
|
||||||
|
QObject *focusObject = m_platformWindow->window()->focusObject();
|
||||||
|
if (auto queryResult = queryInputMethod(focusObject, Qt::ImCurrentSelection)) {
|
||||||
|
QString selectedText = queryResult.value(Qt::ImCurrentSelection).toString();
|
||||||
|
return selectedText.isEmpty() ? NSMakeRange(0, 0) : NSMakeRange(0, selectedText.length());
|
||||||
|
} else {
|
||||||
|
return NSMakeRange(0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||||
@ -205,30 +247,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSRange)markedRange
|
|
||||||
{
|
|
||||||
NSRange range;
|
|
||||||
if (!m_composingText.isEmpty()) {
|
|
||||||
range.location = 0;
|
|
||||||
range.length = m_composingText.length();
|
|
||||||
} else {
|
|
||||||
range.location = NSNotFound;
|
|
||||||
range.length = 0;
|
|
||||||
}
|
|
||||||
return range;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSRange)selectedRange
|
|
||||||
{
|
|
||||||
QObject *focusObject = m_platformWindow->window()->focusObject();
|
|
||||||
if (auto queryResult = queryInputMethod(focusObject, Qt::ImCurrentSelection)) {
|
|
||||||
QString selectedText = queryResult.value(Qt::ImCurrentSelection).toString();
|
|
||||||
return selectedText.isEmpty() ? NSMakeRange(0, 0) : NSMakeRange(0, selectedText.length());
|
|
||||||
} else {
|
|
||||||
return NSMakeRange(0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange
|
||||||
{
|
{
|
||||||
Q_UNUSED(aRange);
|
Q_UNUSED(aRange);
|
||||||
@ -251,18 +269,4 @@
|
|||||||
return NSNotFound;
|
return NSNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray<NSString *> *)validAttributesForMarkedText
|
|
||||||
{
|
|
||||||
if (!m_platformWindow)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
if (m_platformWindow->window() != QGuiApplication::focusWindow())
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
if (queryInputMethod(m_platformWindow->window()->focusObject()))
|
|
||||||
return @[NSUnderlineColorAttributeName, NSUnderlineStyleAttributeName];
|
|
||||||
else
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Loading…
Reference in New Issue
Block a user