using EditTextActivity<DerivedType>::atspiText;
using EditTextActivity<DerivedType>::getAtspiInterfaces;
using EditTextActivity<DerivedType>::markAsCompleted;
+
void process() override
{
- //TODO SelectionMode
getAtspiInterfaces();
- move(DerivedType::DIRECTION, getGranularity());
+ move(DerivedType::DIRECTION, getGranularity(), getMode());
markAsCompleted();
}
NEXT = true
};
+ enum class Mode {
+ EDITION = 1,
+ SELECTION
+ };
+
Atspi::Granularity getGranularity()
{
- auto vconfValue = Singleton<VConfInterface>::instance().get(VCONF_KEY_GRANULARITY_UNIT, 1);
- auto ret = static_cast<Atspi::Granularity>(vconfValue);
- if (ret >= Atspi::Granularity::CHAR && ret <= Atspi::Granularity::PARAGRAPH)
- return ret;
- else
- return Atspi::Granularity::CHAR;
+ return valueInBounds(
+ static_cast<Atspi::Granularity>(Singleton<VConfInterface>::instance().get(VCONF_KEY_GRANULARITY_UNIT, 1)),
+ Atspi::Granularity::CHAR,
+ Atspi::Granularity::PARAGRAPH,
+ Atspi::Granularity::CHAR);
+ }
+
+ Mode getMode()
+ {
+ return valueInBounds(
+ static_cast<Mode>(Singleton<VConfInterface>::instance().get(VCONF_KEY_TEXT_EDITION_MODE, 1)),
+ Mode::EDITION,
+ Mode::SELECTION,
+ Mode::EDITION);
}
- void move(const Direction direction, const Atspi::Granularity granularity)
+ void move(const Direction direction, const Atspi::Granularity granularity, const Mode mode = Mode::EDITION)
{
const auto currentSelectionRange = atspi->getTextSelection(atspiText);
+ if (mode == Mode::SELECTION) {
+ selectByGranularityUnit(direction, granularity, currentSelectionRange);
+ return;
+ }
+
if (currentSelectionRange)
moveToSelectionLimit(direction, granularity, *currentSelectionRange);
else
}
private:
+ template<typename T>
+ T valueInBounds(T value, const T &lowerLimit, const T &upperLimit, const T &defaultValue)
+ {
+ if (value < lowerLimit || value > upperLimit)
+ value = defaultValue;
+
+ return value;
+ }
+
void moveToSelectionLimit(const Direction direction, const Atspi::Granularity granularity, const TextRange currentSelectionRange)
{
auto selectionMarker = (direction == Direction::NEXT) ? currentSelectionRange.end : currentSelectionRange.start;
void moveByGranularityUnit(const Direction direction, const Atspi::Granularity granularity)
{
const auto offset = atspi->getTextCaretOffset(atspiText);
- const auto limit = atspi->countTextCharacters(atspiText);
- if (!offset || !limit)
+ if (!offset)
+ return;
+
+ const auto finalOffset = getLimitOfAdjoiningGranularityUnit(direction, granularity, *offset);
+ DEBUG("Moving caret from: %d to: %d", *offset, finalOffset);
+ atspi->setTextCaretOffset(atspiText, finalOffset);
+ }
+
+ void selectByGranularityUnit(const Direction direction, const Atspi::Granularity granularity, const Optional<TextRange> range)
+ {
+ const auto offset = atspi->getTextCaretOffset(atspiText);
+ if (!offset)
return;
- auto currentOffset = *offset;
+ const auto finalOffset = getLimitOfAdjoiningGranularityUnit(direction, granularity, *offset);
+ const auto newSelection = TextRange {*offset, finalOffset};
+ const auto finalSelection = range ? compareNewSelectionWithOldOne(direction, newSelection, *range) : newSelection;
+
+ DEBUG("Selectiong from from: %d to: %d", finalSelection.start, finalSelection.end);
+ atspi->setTextSelection(atspiText, finalSelection);
+ atspi->setTextCaretOffset(atspiText, finalOffset);
+ }
+
+ TextRange compareNewSelectionWithOldOne(const Direction direction, TextRange newSelection, const TextRange oldSelection)
+ {
+ if (direction == Direction::PREV)
+ return (newSelection.end == oldSelection.end) ?
+ TextRange {oldSelection.start, newSelection.start} :
+ TextRange {newSelection.start, oldSelection.end};
+
+ return (newSelection.start == oldSelection.start) ?
+ TextRange {newSelection.end, oldSelection.end} :
+ TextRange {oldSelection.start, newSelection.end};
+
+ }
+
+ size_t getLimitOfAdjoiningGranularityUnit(const Direction direction, const Atspi::Granularity granularity, const size_t offset)
+ {
+ auto currentOffset = offset;
+ const auto limit = atspi->countTextCharacters(atspiText);
+ if (!limit)
+ return offset;
+
auto range = atspi->getTextRangeAtOffset(atspiText, currentOffset, granularity);
if (!range)
- return;
+ return offset;
auto finalOffset = range->end;
}
range = atspi->getTextRangeAtOffset(atspiText, currentOffset, granularity);
if (!range)
- return;
+ return offset;
finalOffset = range->end;
} while (currentOffset > finalOffset);
range = atspi->getTextRangeAtOffset(atspiText, currentOffset, granularity);
if (!range)
- return;
+ return offset;
finalOffset = range->start;
}
- DEBUG("Moving caret from: %d to: %d", *offset, finalOffset);
- atspi->setTextCaretOffset(atspiText, finalOffset);
+ return finalOffset;
}
};