Компоненты для редактирования многострочного текста

Редактирование текста — одна из самых востребованных операций при работе на ПК, и это верно не только для случая невизуального использования ИТ. Вместе с тем, когда редактирование текста производится в невизуальном режиме, появляются дополнительные требования к реализации элементов управления, отвечающих за подобную функциональность. На этой странице мы рассмотрим основные детали и правила внутренней реализации той части LUWRAIN, которая отвечает за редактирование многострочного текста (LUWRAIN различает случаи, когда редактируется однострочный и многострочный текст).

Невизуальное редактирование текста — это процесс, состоящий из последовательности элементарных и комплексных операций, приводящих к согласованному изменению состояний двух объектов: линейного массива строк и курсора, положение которого задаётся парой координат на плоскости. Реализация соответствующих элементов управления должна быть достаточно гибкой, чтобы отвечать следующим требованиям:

  1. Корректировка каждого действия пользователя должна быть расширяемой, то есть должна существовать возможность построить целостную реакцию, состоящую из некоторого множества отдельных корректировок, часть из которых активизируется для всех элементов управления в системе, другая часть только для элементов управления, содержащих некоторый конкретный тип текста (естественный язык, язык программирования и пр.), третья часть активизируется только для конкретного приложения и т. д.
  2. Добавления новых корректировок должно осуществляться как на низком уровне с использованием Java, являющегося основным языком реализации LUWRAIN, так и на более высоком уровне с использованием пользовательских скриптов (в случае LUWRAIN на языке JavaScript).
  3. Звуковое анонсирование операции с использованием речевого вывода и коротких звуковых сигналов должно быть максимально согласовано с характером произошедших изменений.
  4. Любые задержки реакции на действия пользователя должны быть предельно минимизированы.

Существует несколько различных стилей редактирования текста. Среди них можно выделить стиль GNU Emacs, стиль Microsoft Word и множество других, поэтому LUWRAIN не стремиться следовать конкретному из них (даже при том, что GNU Emacs оказал максимальное влияние на традиции LUWRAIN), а предлагает как можно более широкие возможности по реализации того стиля редактирования текста, который будет привычен конкретному пользователю.

Классы LUWRAIN, отвечающие за редактирование многострочного текста, организованы в следущую цепочку:

  1. Основной элемент управления, получающий команды пользователя (класс org.luwrain.controls.MultilineTextEdit)
  2. Интерфейс модели элемента управления (org.luwrain.controls.MultilineEdit.Model).
  3. Цепочка классов-корректоров (экземпляры классов, реализующих интерфейс org.luwrain.controls.MultilineEditCorrector).
  4. Базовый интерпретатор операций редактирования (класс org.luwrain.controls.MultilineEditTranslator).
  5. Две базовые структуры, хранящие информацию о тексте: массив строк и положение курсора.

Ниже все операции редактирования будут разделяться на элементарные и комплексные. Все элементарные операции представлены методами интерфейса org.luwrain.controls.MultilineEdit.Model:

  1. Вставка одного или нескольких символов (putChars()).
  2. Удаление символа в заданной позиции (deleteChar()).
  3. Вставка фрагмента текста (insertRegion()).
  4. Удаление фрагмента текста между двумя заданными позициями (deleteRegion()).
  5. Объединение двух соседних строк (mergeLines()).
  6. Разбиение строки на две в заданной позиции (splitLine()).

Как нетрудно заметить, все элементарные действия пользователя по редактированию текста сводятся к одной (и строго одной) из вышеперечисленных операций. Работа с фрагментами предусмотрена для операций копирования-вставки с буфером обмена. Реализация модели элемента управления должна соответствовать следующим требованиям:

  1. Положение курсора модель обновляет самостоятельно. Выполнение каждой операции может быть запрошено в любой позиции, и курсор должен получить новое положение автоматически.
  2. Если выполнение операции было подменено любой комбинацией других операций, то все структуры должны остаться в согласованном состоянии.

В списке операций нет каких-либо действий по управлению положением курсора, поскольку весь интерфейс LUWRAIN построен таким образом, что навигация по пространству пользователя реализована по типу навигации в тексте. Создавать отдельные операций только для редактирования текста нет необходимости. Все методы в качестве результата своего выполнения возвращают объект класса org.luwrain.controls.MultilineEdit.ModificationResult, но к нему мы вернёмся позже.

Корректорами мы называем классы, которые должны как-либо дополнять или модифицировать действия пользователя при редактировании текста. Примером корректора может быть класс, который в случае перехода на новую строку автоматически добавляет отступ, как это бывает при редактировании исходников. Корректоры должны удовлетворять интерфейсу org.lluwrain.controls.MultilineEditCorrector Этот интерфейс сохраняет все операции org.luwrain.controls.MultilineEdit.Model, но добавляет к ним возможность выполнения какой-либо комплексной операции редактирования. Комплексными мы называем все операции, которые не могут быть сведены к операциям модели без нарушения вышеперечисленных требований к ней. Примерами таких операций могут быть замена по регулярному выражению, автоматическое выравнивание текста в столбец и др.

Реализация корректора обычно работает поверх другого корректора или на самом нижнем уровне поверх базового интерпретатора редактирования. Модификация любой операций производится путём её подмены на любую комбинацию операций нижележащего корректора. Возможностью выполнить комплексную операцию для нижележащего корректора не стоит злоупотреблять, поскольку это действие будет непрозрачным для всех нижележащих корректоров. Это следует делать исключительно только в тех случаях, когда операция не может быть разбита на элементарные операции, разбиение приведёт к неэффективным вычислениям или в случае преднамеренной попытки избежать обработки операции со стороны нижележащих корректоров.

В остальном каждый корректор вправе вносить любую модификацию в поведение нижележащего корректора. Это основное место для реализации каких-либо частных процедур, отвечающих за поведение элемента управления для редактирования многострочного текста. Корректоры организуются в цепочку, в самом конце которой находится базовый интерпретатор операций редактирования, в свою очередь тоже реализующий интерфейс org.luwrain.controls.MultilineEditCorrector, т. е. тоже являющийся корректором. Ядро LUWRAIN способно по запросу приложения создать общесистемные корректоры, которые будут работать поверх некоторого заданного корректора. Приложение имеет возможность отказаться от использования общесистемных корректоров, но в этом случае не будут работать некоторые операции, которые пользователь пожелал активизировать для всех полей редактирования текста в своей системе. За создание общесистемных корректоров отвечает метод createSystemwideMultilineEditCorrectors() объекта org.luwrain.core.Luwrain. Он принимает в качестве аргумента множество тегов, характеризующих назначение поля ввода. Примерами таких тегов могут быть "nl" (поле для редактирования текста на естественном языке), "lang:ru" (поле для текста на русском языке) и т. д.

Как упоминалось выше, Каждая операция редактирования возвращает в качестве результата объект класса org.luwrain.controls.MultilineEdit.ModificationResult. Такой объект содержит обязательное булево поле, обозначающее, считается ли операция выполненной или нет, а также два опциональных поля для сохранения символьного атрибута (к примеру, для идентификации символа, стёртого пользователем) и строкового атрибута (какое слово находится в тексте после ввода пробела). Тем не менее, объекты-корректоры могут возвращать любые классы, расширяющие ModificationResult, добавляя в них любые новые атрибуты.

После того, как пользователь совершает некоторую элементарную операцию и модель обрабатывает её с задействованием существующей цепочки корректоров, вызывается соответствующий метод объекта-представления, который формирует звуковой ответ пользователю, уведомляющий об успешности операции и характере произведённых изменений. Объект-представление должен удовлетворять интерфейсу org.luwrain.controls.MultilineEdit.Appearance, и существует его умолчательная реализация org.luwrain.controls.EditUtils.DefaultMultilineEditAppearance. Вызываемый метод соответствует назначению выполненной операции, причём ему передаётся объект класса ModificationResult, полученный в ходе выполнения. Это действие совершается в любом случае, даже если объект ModificationResult имеет сброшенный флаг успешности. Предоставляя частную реализацию интерфейса -Appearance_, которая, очевидно, должна быть так или иначе согласована с особенностями используемой цепочки корректоров, разработчик может добиться любого желаемого поведения редактора текста. Анонсирование пользователю комплексных операций всегда выполняет объект, вызывающий операцию.

Вышеизложенное описание охватывает все вопросы обработки операций редактирование многострочного текста в случае разработки на низком уровне, т. е. при программировании на уровне классов Java.

DirectScriptMultilineEditCorrector

© 2012–2020 Разработчики LUWRAIN
Дизайн от Strash