Sending appropriate text change signals instead of a single cursor change signal
This commit is contained in:
parent
cf92542bc5
commit
65f56d02ee
13 changed files with 144 additions and 50 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue