Sending appropriate text change signals instead of a single cursor change signal

This commit is contained in:
Eism 2022-02-02 16:58:56 +02:00
parent cf92542bc5
commit 65f56d02ee
13 changed files with 144 additions and 50 deletions

View file

@ -295,7 +295,7 @@ QString AccessibleItem::accessibleTextAtOffset(int offset, TextBoundaryType boun
return result;
}
int AccessibleItem::accesibleCharacterCount() const
int AccessibleItem::accessibleCharacterCount() const
{
if (!m_element || !m_element->isTextBase()) {
return 0;
@ -338,7 +338,7 @@ QRect AccessibleItem::accessibleRect() const
return rect;
}
mu::async::Channel<IAccessible::Property> AccessibleItem::accessiblePropertyChanged() const
mu::async::Channel<IAccessible::Property, mu::Val> AccessibleItem::accessiblePropertyChanged() const
{
return m_accessiblePropertyChanged;
}

View file

@ -75,9 +75,9 @@ public:
QString accessibleText(int startOffset, int endOffset) const override;
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
int accesibleCharacterCount() const override;
int accessibleCharacterCount() const override;
async::Channel<Property> accessiblePropertyChanged() const override;
async::Channel<Property, Val> accessiblePropertyChanged() const override;
async::Channel<State, bool> accessibleStateChanged() const override;
// ---
@ -93,7 +93,7 @@ protected:
Role m_role = Role::ElementOnScore;
mu::async::Channel<IAccessible::Property> m_accessiblePropertyChanged;
mu::async::Channel<IAccessible::Property, Val> m_accessiblePropertyChanged;
mu::async::Channel<IAccessible::State, bool> m_accessibleStateChanged;
};
}

View file

@ -3064,6 +3064,25 @@ AccessibleItem* TextBase::createAccessible()
return new AccessibleItem(this, AccessibleItem::EditableText);
}
void TextBase::notifyAboutTextCursorChanged()
{
accessible()->accessiblePropertyChanged().send(accessibility::IAccessible::Property::TextCursor, Val());
}
void TextBase::notifyAboutTextInserted(int startPosition, int endPosition, const QString& text)
{
auto range = accessibility::IAccessible::TextRange(startPosition, endPosition, text);
accessible()->accessiblePropertyChanged().send(accessibility::IAccessible::Property::TextInsert,
Val(range.toMap()));
}
void TextBase::notifyAboutTextRemoved(int startPosition, int endPosition, const QString& text)
{
auto range = accessibility::IAccessible::TextRange(startPosition, endPosition, text);
accessible()->accessiblePropertyChanged().send(accessibility::IAccessible::Property::TextRemove,
Val(range.toMap()));
}
//---------------------------------------------------------
// getPropertyStyle
//---------------------------------------------------------

View file

@ -313,6 +313,10 @@ class TextBase : public EngravingItem
mu::engraving::AccessibleItem* createAccessible() override;
void notifyAboutTextCursorChanged();
void notifyAboutTextInserted(int startPosition, int endPosition, const QString& text);
void notifyAboutTextRemoved(int startPosition, int endPosition, const QString& text);
protected:
TextBase(const ElementType& type, EngravingItem* parent = 0, TextStyleType tid = TextStyleType::DEFAULT,
ElementFlags = ElementFlag::NOTHING);

View file

@ -27,6 +27,8 @@
#include "scorefont.h"
#include "types/symnames.h"
#include "accessibility/accessibleitem.h"
#include "log.h"
using namespace mu;
@ -310,6 +312,9 @@ bool TextBase::edit(EditData& ed)
case Qt::Key_Return:
deleteSelectedText(ed);
score()->undo(new SplitText(cursor), &ed);
notifyAboutTextCursorChanged();
return true;
case Qt::Key_Delete:
@ -325,16 +330,28 @@ bool TextBase::edit(EditData& ed)
} else {
score()->undo(new RemoveText(cursor, QString(cursor->currentCharacter())), &ed);
}
// notifyAboutTextRemoved() // todo
}
return true;
case Qt::Key_Backspace:
case Qt::Key_Backspace: {
int startPosition = cursor->currentPosition();
if (ctrlPressed) {
// delete last word
cursor->movePosition(TextCursor::MoveOperation::WordLeft, TextCursor::MoveMode::KeepAnchor);
int endPosition = cursor->currentPosition();
QString text = cursor->selectedText();
s.clear();
deleteSelectedText(ed);
if (deleteSelectedText(ed)) {
notifyAboutTextRemoved(startPosition, endPosition, text);
}
} else {
QString text = cursor->selectedText();
if (!deleteSelectedText(ed)) {
if (cursor->column() == 0 && _cursor->row() != 0) {
score()->undo(new JoinText(cursor), &ed);
@ -344,9 +361,12 @@ bool TextBase::edit(EditData& ed)
}
score()->undo(new RemoveText(cursor, QString(cursor->currentCharacter())), &ed);
}
} else {
notifyAboutTextRemoved(startPosition, startPosition - 1, text);
}
}
return true;
}
case Qt::Key_Left:
if (!_cursor->movePosition(ctrlPressed ? TextCursor::MoveOperation::WordLeft : TextCursor::MoveOperation::Left,
@ -354,6 +374,9 @@ bool TextBase::edit(EditData& ed)
return false;
}
s.clear();
notifyAboutTextCursorChanged();
break;
case Qt::Key_Right:
@ -362,6 +385,9 @@ bool TextBase::edit(EditData& ed)
return false;
}
s.clear();
notifyAboutTextCursorChanged();
break;
case Qt::Key_Up:
@ -373,6 +399,9 @@ bool TextBase::edit(EditData& ed)
cursor->movePosition(TextCursor::MoveOperation::Up, mm);
#endif
s.clear();
notifyAboutTextCursorChanged();
break;
case Qt::Key_Down:
@ -384,6 +413,9 @@ bool TextBase::edit(EditData& ed)
cursor->movePosition(TextCursor::MoveOperation::Down, mm);
#endif
s.clear();
notifyAboutTextCursorChanged();
break;
case Qt::Key_Home:
@ -394,6 +426,9 @@ bool TextBase::edit(EditData& ed)
}
s.clear();
notifyAboutTextCursorChanged();
break;
case Qt::Key_End:
@ -404,6 +439,9 @@ bool TextBase::edit(EditData& ed)
}
s.clear();
notifyAboutTextCursorChanged();
break;
case Qt::Key_Tab:
@ -442,6 +480,8 @@ bool TextBase::edit(EditData& ed)
cursor->movePosition(TextCursor::MoveOperation::Start, TextCursor::MoveMode::MoveAnchor);
cursor->movePosition(TextCursor::MoveOperation::End, TextCursor::MoveMode::KeepAnchor);
s.clear();
notifyAboutTextCursorChanged();
}
break;
case Qt::Key_B:
@ -519,6 +559,9 @@ bool TextBase::edit(EditData& ed)
if (!s.isEmpty()) {
deleteSelectedText(ed);
score()->undo(new InsertText(_cursor, s), &ed);
int startPosition = cursor->currentPosition();
notifyAboutTextInserted(startPosition, startPosition + s.size(), s);
}
return true;
}

View file

@ -23,10 +23,14 @@
#define MU_ACCESSIBILITY_IACCESSIBLE_H
#include <utility>
#include <QString>
#include <QRect>
#include <QVariant>
#include <QMap>
#include "async/channel.h"
#include "val.h"
class QWindow;
@ -75,7 +79,9 @@ public:
Name,
Description,
Value,
Selection
TextCursor,
TextInsert,
TextRemove
};
enum TextBoundaryType {
@ -87,6 +93,30 @@ public:
NoBoundary
};
struct TextRange {
int startPosition = 0;
int endPosition = 0;
QString text;
TextRange(int startPosition, int endPosition, const QString& text)
: startPosition(startPosition), endPosition(endPosition), text(text) {}
TextRange(const QVariantMap& map)
{
startPosition = map.value("startPosition").toInt();
endPosition = map.value("endPosition").toInt();
text = map.value("startPosition").toString();
}
QVariantMap toMap() const
{
return {
{ "startPosition", startPosition },
{ "endPosition", endPosition },
{ "text", text }
};
}
};
virtual const IAccessible* accessibleParent() const = 0;
virtual size_t accessibleChildCount() const = 0;
virtual const IAccessible* accessibleChild(size_t i) const = 0;
@ -111,9 +141,9 @@ public:
virtual QString accessibleText(int startOffset, int endOffset) const = 0;
virtual QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const = 0;
virtual int accesibleCharacterCount() const = 0;
virtual int accessibleCharacterCount() const = 0;
virtual async::Channel<IAccessible::Property> accessiblePropertyChanged() const = 0;
virtual async::Channel<IAccessible::Property, Val> accessiblePropertyChanged() const = 0;
virtual async::Channel<IAccessible::State, bool> accessibleStateChanged() const = 0;
};
}

View file

@ -110,8 +110,8 @@ void AccessibilityController::reg(IAccessible* item)
m_children.append(item);
}
item->accessiblePropertyChanged().onReceive(this, [this, item](const IAccessible::Property& p) {
propertyChanged(item, p);
item->accessiblePropertyChanged().onReceive(this, [this, item](const IAccessible::Property& p, const Val value) {
propertyChanged(item, p, value);
});
item->accessibleStateChanged().onReceive(this, [this, item](const State& state, bool arg) {
@ -155,7 +155,7 @@ const IAccessible* AccessibilityController::lastFocused() const
return m_lastFocused;
}
void AccessibilityController::propertyChanged(IAccessible* item, IAccessible::Property p)
void AccessibilityController::propertyChanged(IAccessible* item, IAccessible::Property property, const Val& value)
{
const Item& it = findItem(item);
if (!it.isValid()) {
@ -163,7 +163,7 @@ void AccessibilityController::propertyChanged(IAccessible* item, IAccessible::Pr
}
QAccessible::Event etype = QAccessible::InvalidEvent;
switch (p) {
switch (property) {
case IAccessible::Property::Undefined:
return;
case IAccessible::Property::Parent: etype = QAccessible::ParentChanged;
@ -177,11 +177,25 @@ void AccessibilityController::propertyChanged(IAccessible* item, IAccessible::Pr
sendEvent(&ev);
return;
}
case IAccessible::Property::Selection: {
case IAccessible::Property::TextCursor: {
QAccessibleTextCursorEvent ev(it.object, it.item->accessibleCursorPosition());
sendEvent(&ev);
return;
}
case IAccessible::Property::TextInsert: {
IAccessible::TextRange range(value.toQVariant().toMap());
QAccessibleTextInsertEvent ev(it.object, range.startPosition,
it.item->accessibleText(range.startPosition, range.endPosition));
sendEvent(&ev);
return;
}
case IAccessible::Property::TextRemove: {
IAccessible::TextRange range(value.toQVariant().toMap());
QAccessibleTextRemoveEvent ev(it.object, range.startPosition,
it.item->accessibleText(range.startPosition, range.endPosition));
sendEvent(&ev);
return;
}
}
QAccessibleEvent ev(it.object, etype);
@ -477,14 +491,14 @@ QString AccessibilityController::accessibleTextAtOffset(int, TextBoundaryType, i
return QString();
}
int AccessibilityController::accesibleCharacterCount() const
int AccessibilityController::accessibleCharacterCount() const
{
return 0;
}
mu::async::Channel<IAccessible::Property> AccessibilityController::accessiblePropertyChanged() const
mu::async::Channel<IAccessible::Property, mu::Val> AccessibilityController::accessiblePropertyChanged() const
{
static async::Channel<IAccessible::Property> ch;
static async::Channel<IAccessible::Property, Val> ch;
return ch;
}

View file

@ -94,9 +94,9 @@ public:
QString accessibleText(int startOffset, int endOffset) const override;
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
int accesibleCharacterCount() const override;
int accessibleCharacterCount() const override;
async::Channel<Property> accessiblePropertyChanged() const override;
async::Channel<Property, Val> accessiblePropertyChanged() const override;
async::Channel<State, bool> accessibleStateChanged() const override;
// -----
@ -125,7 +125,7 @@ private:
const Item& findItem(const IAccessible* aitem) const;
void propertyChanged(IAccessible* item, IAccessible::Property p);
void propertyChanged(IAccessible* item, IAccessible::Property property, const Val& value);
void stateChanged(IAccessible* item, IAccessible::State state, bool arg);
void sendEvent(QAccessibleEvent* ev);

View file

@ -334,7 +334,7 @@ QString AccessibleItemInterface::textAtOffset(int offset, QAccessible::TextBound
int AccessibleItemInterface::characterCount() const
{
return m_object->item()->accesibleCharacterCount();
return m_object->item()->accessibleCharacterCount();
}
QRect AccessibleItemInterface::characterRect(int) const

View file

@ -82,9 +82,9 @@ public:
QString accessibleText(int, int) const override { return QString(); }
QString accessibleTextAtOffset(int, TextBoundaryType, int*, int*) const override { return QString(); }
int accesibleCharacterCount() const override { return 0; }
int accessibleCharacterCount() const override { return 0; }
async::Channel<IAccessible::Property> accessiblePropertyChanged() const override
async::Channel<IAccessible::Property, Val> accessiblePropertyChanged() const override
{
return m_propertyChanged;
}
@ -94,7 +94,7 @@ public:
return m_stateChanged;
}
async::Channel<IAccessible::Property> m_propertyChanged;
async::Channel<IAccessible::Property, Val> m_propertyChanged;
async::Channel<IAccessible::State, bool> m_stateChanged;
AccessibleItem* m_parent = nullptr;

View file

@ -189,12 +189,12 @@ QString AccessibleItem::accessibleTextAtOffset(int, TextBoundaryType, int*, int*
return QString();
}
int AccessibleItem::accesibleCharacterCount() const
int AccessibleItem::accessibleCharacterCount() const
{
return 0;
}
mu::async::Channel<IAccessible::Property> AccessibleItem::accessiblePropertyChanged() const
mu::async::Channel<IAccessible::Property, mu::Val> AccessibleItem::accessiblePropertyChanged() const
{
return m_accessiblePropertyChanged;
}
@ -226,7 +226,7 @@ void AccessibleItem::setAccessibleParent(AccessibleItem* p)
}
emit accessiblePrnChanged();
m_accessiblePropertyChanged.send(IAccessible::Property::Parent);
m_accessiblePropertyChanged.send(IAccessible::Property::Parent, Val());
}
void AccessibleItem::setState(IAccessible::State st, bool arg)
@ -268,7 +268,7 @@ void AccessibleItem::setName(QString name)
m_name = name;
emit nameChanged(m_name);
m_accessiblePropertyChanged.send(IAccessible::Property::Name);
m_accessiblePropertyChanged.send(IAccessible::Property::Name, Val(name));
}
void AccessibleItem::setDescription(QString description)
@ -279,7 +279,7 @@ void AccessibleItem::setDescription(QString description)
m_description = description;
emit descriptionChanged(m_description);
m_accessiblePropertyChanged.send(IAccessible::Property::Description);
m_accessiblePropertyChanged.send(IAccessible::Property::Description, Val(description));
}
void AccessibleItem::setValue(QVariant value)
@ -290,7 +290,7 @@ void AccessibleItem::setValue(QVariant value)
m_value = value;
emit valueChanged(m_value);
m_accessiblePropertyChanged.send(IAccessible::Property::Value);
m_accessiblePropertyChanged.send(IAccessible::Property::Value, Val(value));
}
void AccessibleItem::setMaximumValue(QVariant maximumValue)

View file

@ -135,9 +135,9 @@ public:
QString accessibleText(int startOffset, int endOffset) const override;
QString accessibleTextAtOffset(int offset, TextBoundaryType boundaryType, int* startOffset, int* endOffset) const override;
int accesibleCharacterCount() const override;
int accessibleCharacterCount() const override;
async::Channel<Property> accessiblePropertyChanged() const override;
async::Channel<Property, Val> accessiblePropertyChanged() const override;
async::Channel<State, bool> accessibleStateChanged() const override;
// -----
@ -186,7 +186,7 @@ private:
bool m_ignored = false;
QQuickItem* m_visualItem = nullptr;
QMap<State, bool> m_state;
async::Channel<Property> m_accessiblePropertyChanged;
async::Channel<Property, Val> m_accessiblePropertyChanged;
async::Channel<State, bool> m_accessibleStateChanged;
};
}

View file

@ -178,19 +178,6 @@ void NotationInteraction::notifyAboutTextEditingChanged()
m_textEditingChanged.notify();
}
void NotationInteraction::notifyAboutTextCursorChanged()
{
if (!m_editData.element || !m_editData.element->isTextBase()) {
return;
}
Ms::TextBase* text = toTextBase(m_editData.element);
auto accessibleItem = text->accessible();
if (accessibleItem) {
accessibleItem->accessiblePropertyChanged().send(AccessibleItem::Property::Selection);
}
}
void NotationInteraction::notifyAboutSelectionChanged()
{
updateGripEdit();
@ -2473,7 +2460,6 @@ void NotationInteraction::editText(QInputMethodEvent* event)
event->accept();
notifyAboutTextEditingChanged();
notifyAboutTextCursorChanged();
}
static qreal nudgeDistance(const Ms::EditData& editData)
@ -2600,7 +2586,6 @@ void NotationInteraction::changeTextCursorPosition(const PointF& newCursorPos)
}
notifyAboutTextEditingChanged();
notifyAboutTextCursorChanged();
}
const TextBase* NotationInteraction::editedText() const
@ -2775,7 +2760,6 @@ void NotationInteraction::editElement(QKeyEvent* event)
}
if (isTextEditingStarted()) {
notifyAboutTextEditingChanged();
notifyAboutTextCursorChanged();
} else {
if (bracketIndex >= 0 && systemIndex < score()->systems().size()) {
Ms::System* sys = score()->systems()[systemIndex];