TPDFlibFormSession

Формы, взаимодействие, типы данных

Описание

Поддерживает проверку попадания AcroForm, навигацию с клавиатуры, фокус, редактируемое значение и состояние выделения текста без зависимости от GUI-фреймворка Подключённый экземпляр

TPDFlib

Переходы фокуса раскрывают действия /Fo и /Bl виджетов как типизированные колбэки хоста через OnAction

Прямоугольники страниц используют визуальный CropBox после поворота страницы в текущих единицах измерения библиотеки, с началом в визуальном левом верхнем углу

Направленные выделения удерживают независимые позиции якоря и каретки и могут задаваться и запрашиваться в кодовых единицах UTF-16, кодовых точках Unicode или расширенных кластерах графем

Двунаправленные правки удерживают логический порядок значения поля, разрешая построчные визуальные каретные позиции из уровней вложения, поэтому физическое перемещение Left и Right следует смешанному тексту слева направо и справа налево

Замены выделения отправляют /K хосту, раскрывают выделенный и замещающий текст через OnTextEdit, принудительно соблюдают /MaxLen по полным границам графем и сворачивают выделение после одной принятой правки

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

DispatchInputEvent преобразует нейтральные к платформе записи указателя, колеса, именованной клавиши и составленного текста в ограниченные действия виджетов, переходы фокуса, безопасное для графем редактирование, активацию кнопок и навигацию по вариантам выбора

Сессия удерживает идентичность вошедших и нажатых виджетов, чтобы /E, /X, /D и /U следовали правилам порядка триггеров PDF даже через захват и отмену указателя

Подтверждения отправляют действия /V и /F, выполняют их поддерживаемое ограниченное подмножество JavaScript до изменения документа и удерживают активную правку, когда проверка, форматирование или колбэк хоста отклоняет транзакцию

Проверенное необработанное значение сохраняется в поле, тогда как DisplayValue и сгенерированный appearance виджета удерживают любой результат форматирования

Объявление

type
  TPDFlibFormFieldIndices = array of Integer;

  TPDFlibFormSelectionUnit = (fsuUTF16CodeUnit,
    fsuUnicodeCodePoint, fsuGraphemeCluster);

  TPDFlibFormTextDirection = (ftdAuto,
    ftdLeftToRight, ftdRightToLeft);
  TPDFlibFormCaretIndices = array of Integer;

  TPDFlibFormSelection = record
    IndexUnit: TPDFlibFormSelectionUnit;
    AnchorIndex: Integer;
    CaretIndex: Integer;
    StartIndex: Integer;
    SelectionLength: Integer;
    IsReversed: Boolean;
  end;

  TPDFlibFormSessionActionEvent = procedure(Sender: TObject;
    FieldIndex: Integer; const TriggerEvent: AnsiString;
    const ActionInfo: TPDFlibActionInfo; var Allow: Boolean) of object;
  TPDFlibFormSessionFocusEvent = procedure(Sender: TObject;
    OldFieldIndex, NewFieldIndex: Integer) of object;
  TPDFlibFormSessionValueEvent = procedure(Sender: TObject;
    FieldIndex: Integer; const OldValue, NewValue: WideString) of object;
  TPDFlibFormEditKind = (fekReplaceSelection,
    fekCutSelection, fekPasteText);
  TPDFlibFormSessionTextEditEvent = procedure(Sender: TObject;
    FieldIndex: Integer; EditKind: TPDFlibFormEditKind;
    SelectionStart, SelectionLength: Integer;
    const SelectedText: WideString; var ReplacementText: WideString;
    var Allow: Boolean) of object;

  TPDFlibFormInputEventKind = (fiekPointerMove,
    fiekPointerDown, fiekPointerUp, fiekPointerDoubleClick,
    fiekPointerLeave, fiekPointerCancel, fiekWheel,
    fiekKeyDown, fiekKeyUp, fiekTextInput);
  TPDFlibFormInputModifiers = set of TPDFlibFormInputModifier;

  TPDFlibFormInputEvent = record
    Kind: TPDFlibFormInputEventKind;
    Modifiers: TPDFlibFormInputModifiers;
    Button: TPDFlibFormInputButton;
    Key: TPDFlibFormInputKey;
    Page: Integer;
    X, Y: Double;
    WheelDeltaX, WheelDeltaY: Double;
    Text: WideString;
  end;

  TPDFlibFormSession = class
  public
    constructor Create(ALibrary: TPDFlib);
    procedure AttachLibrary(ALibrary: TPDFlib);
    procedure Reset;
    function FocusField(FieldIndex: Integer;
      CommitCurrent: Boolean = True): Integer;
    function GetFieldPageRect(FieldIndex: Integer; out Page: Integer;
      out Left, Top, Width, Height: Double): Integer;
    function HitTest(Page: Integer; X, Y: Double): Integer;
    function GetTabSequence(out FieldIndices: TPDFlibFormFieldIndices): Integer;
    function FocusAt(Page: Integer; X, Y: Double;
      CommitCurrent: Boolean = True): Integer;
    function FocusNext(Backwards: Boolean = False;
      WrapAround: Boolean = True; CommitCurrent: Boolean = True): Integer;
    function Blur(CommitCurrent: Boolean = True): Integer;
    function BeginEdit(FieldIndex: Integer): Integer;
    function SetEditValue(const NewValue: WideString): Integer;
    function SetSelection(StartIndex, SelectionLength: Integer): Integer;
    function SetSelectionRange(AnchorIndex, CaretIndex: Integer;
      IndexUnit: TPDFlibFormSelectionUnit): Integer;
    function GetSelectionRange(IndexUnit: TPDFlibFormSelectionUnit;
      out Selection: TPDFlibFormSelection): Integer;
    function SetTextDirection(
      Direction: TPDFlibFormTextDirection): Integer;
    function GetVisualCaretOrder(IndexUnit: TPDFlibFormSelectionUnit;
      out CaretIndices: TPDFlibFormCaretIndices): Integer;
    function MoveVisualCaret(ToRight: Boolean;
      ExtendSelection: Boolean = False): Integer;
    function GetSelectedText: WideString;
    function ReplaceSelection(const ReplacementText: WideString): Integer;
    function CutSelection(out CutText: WideString): Integer;
    function PasteText(const Text: WideString): Integer;
    function CanUndoEdit: Boolean;
    function CanRedoEdit: Boolean;
    function UndoEdit: Integer;
    function RedoEdit: Integer;
    procedure ClearEditHistory;
    function DispatchInputEvent(
      const InputEvent: TPDFlibFormInputEvent;
      out InputResult: TPDFlibFormInputResult): Integer;
    function CommitEdit: Integer;
    procedure CancelEdit;
    property TextDirection: TPDFlibFormTextDirection;
    property ResolvedTextDirection: TPDFlibFormTextDirection;
    property VisualCaretPosition: Integer;
    property MaxUndoSteps: Integer;
    property UndoEditCount: Integer;
    property RedoEditCount: Integer;
    property HoveredFieldIndex: Integer;
    property PressedFieldIndex: Integer;
  end;

Методы

CreateСоздаёт сеанс, подключённый к принадлежащему вызывающему экземпляру библиотеки
AttachLibraryСбрасывает всё временное состояние и подключает другой принадлежащий вызывающему экземпляр библиотеки или nil
ResetОчищает состояние фокуса, правки и выделения без изменения значений полей и отправки действий
FocusFieldФиксирует или отменяет текущую правку, отправляет /Bl для прежнего Widget, затем отправляет /Fo для запрошенного видимого Widget
GetFieldPageRectВозвращает прямоугольник видимого Widget в повёрнутых визуальных координатах CropBox без смены выбранной страницы
HitTestВозвращает верхний видимый Widget в визуальной точке страницы, используя более поздние записи массива /Annots страницы как передний план
GetTabSequenceВозвращает видимые Widget между страницами в порядке страниц и применяет семантику /Tabs /R, /C, /S, PDF 2.0 /A и /W, поворот страницы и ViewerPreferences /Direction; отсутствующее или недопустимое значение /Tabs использует порядок массива аннотаций
FocusAtПроверяет попадание в визуальную точку страницы и фокусирует возвращённый Widget через обычный путь фиксации, разфокусировки и действия фокуса
FocusNextПеремещается вперёд или назад по вычисленной последовательности табуляции с необязательным циклическим переходом и обычными правилами перехода фокуса
BlurФиксирует или отменяет текущую правку и отправляет /Bl перед очисткой фокуса
BeginEditФокусирует редактируемое текстовое поле или поле выбора и снимает его исходное значение
SetEditValueОбновляет текущее значение и соблюдает настроенную максимальную длину текстового поля, не разрезая расширенную графемную группу
SetSelectionОграничивает и сохраняет диапазон выделения UTF-16 с базой 0 внутри текущего значения
SetSelectionRangeОграничивает направленные позиции якоря и курсора в запрошенной единице индекса, преобразует их во внутренний диапазон UTF-16 и никогда не разрезает кодовую точку или графемную группу при использовании любой из Unicode-единиц
GetSelectionRangeВозвращает якорь, курсор, нормализованные начало и длину в запрошенной единице индекса вместе с исходным направлением
SetTextDirectionВыбирает автоматическое, явное слева направо или явное справа налево направление абзаца и делает недействительным кэшированный визуальный порядок курсора
GetVisualCaretOrderВозвращает безопасные по графемам логические индексы курсора в физическом порядке слева направо, включая отдельные разделённые слоты на границах смешанных направлений
MoveVisualCaretПеремещает или расширяет направленное выделение на один физический визуальный слот и сворачивает существующие выделения к запрошенному физическому краю
GetSelectedTextВозвращает текущий выделенный текст UTF-16 или пустую строку
ReplaceSelectionЗаменяет нормализованное выделение одной подлежащей вето транзакцией /K и OnTextEdit, затем сворачивает курсор после принятой замены
CutSelectionВозвращает и удаляет выделенный текст через тот же атомарный путь замены
PasteTextЗаменяет текущее выделение текстом буфера обмена, переданным вызывающей стороной, не вводя зависимости от платформенного буфера обмена
CanUndoEditСообщает, есть ли у активной правки запись истории, которую можно обратить
CanRedoEditСообщает, есть ли у активной правки обращённая запись истории, которую можно воспроизвести
UndoEditОбращает последнюю сохранённую правку и восстанавливает её прежнее направленное выделение
RedoEditВоспроизводит следующую сохранённую правку и восстанавливает её результирующее направленное выделение
ClearEditHistoryОтбрасывает историю отмены и повтора активной правки, не меняя её текущее значение или выделение
DispatchInputEventОтправляет одно не зависящее от платформы событие указателя, колёсика, клавиши или составного текста и возвращает результирующее состояние фокуса, наведения, нажатия, значения и выделения
CommitEditПроверяет и форматирует кандидата перед сохранением его необработанного значения, обновляет отформатированный внешний вид, затем вызывает OnValueChanged
CancelEditОтбрасывает текущее значение и выделение без изменения поля

Свойства состояния

LibraryInstanceТекущий не владеемый экземпляр TPDFlib
FocusedFieldIndexСфокусированное поле или временный индекс Widget, либо ноль, когда ни один Widget не в фокусе
EditingFieldIndexРедактируемое базовое текстовое поле или поле выбора, либо ноль, когда правка не активна
OriginalValueЗначение поля, зафиксированное BeginEdit
EditValueТекущее временное значение
DisplayValueТекущее значение правки или отформатированное отображаемое значение последней успешной фиксации
SelectionStartНачальный индекс UTF-16 с базой 0
SelectionLengthДлина выделения UTF-16
SelectionAnchorПозиция якоря UTF-16 с базой 0, остающаяся неподвижной, пока курсор расширяет направленное выделение
SelectionCaretПодвижная граница направленного выделения UTF-16 с базой 0
TextDirectionНастроенное направление, по умолчанию ftdAuto, сохраняется между правками в сеансе
ResolvedTextDirectionЯвное направление или автоматическое направление, выбранное по первому сильному символу значения активной правки
VisualCaretPositionТекущий слот в кэшированном физическом порядке курсора или -1, когда ни одно визуальное перемещение не выбрало слот
MaxUndoStepsМаксимум удерживаемых записей истории правок от 0 до 10000; по умолчанию 1000, ноль отключает запись
UndoEditCountЧисло удерживаемых записей, доступных в данный момент UndoEdit
RedoEditCountЧисло удерживаемых записей, доступных в данный момент RedoEdit
ModifiedTrue, когда EditValue отличается от OriginalValue
HoveredFieldIndexWidget с активным в данный момент состоянием входа указателя, либо ноль
PressedFieldIndexWidget, удерживающий захват основного указателя до соответствующего отпускания или отмены указателя, либо ноль

События

OnActionПолучает типизированную структуру TPDFlibActionInfo для доступных действий фокуса, разфокусировки, нажатия клавиши, проверки и форматирования; установите Allow в False, чтобы отклонить отложенную операцию
OnFocusChangedСообщает каждый завершённый переход фокуса, включая переходы к нулю после отклонённого нового действия фокуса
OnValueChangedСообщает успешно зафиксированное изменение значения после обновления поля и его изменённых внешних видов
OnTextEditПолучает вид правки, выделение UTF-16, выделенный текст и изменяемую замену до изменения текущего значения; установите Allow в False для атомарного отклонения

Возвращаемое значение

Функции, меняющие состояние, возвращают 1 при успехе и 0, когда запрос недопустим, реентерабелен, отклонён или не может быть зафиксирован; HitTest возвращает индекс поля или временного Widget, а GetTabSequence — число записей

Единицы выбора

fsuUTF16CodeUnit сохраняет прежний контракт индексации WideString с базой 0, включая позиции внутри суррогатной пары при явном запросе

fsuUnicodeCodePoint считает допустимую суррогатную пару одной дополнительной кодовой точкой и трактует непарный суррогат как одну самостоятельную кодовую точку

fsuGraphemeCluster считает полные расширенные кластеры графем, поэтому комбинируемые последовательности и склеенные эмодзи остаются неделимыми

Таблицы границ Unicode кэшируются для текущего значения правки и инвалидизируются при его изменении

Двунаправленная навигация

ftdAuto использует первый сильный символ и по умолчанию выбирает слева направо, когда в правке нет сильного направленного символа

Визуальный порядок прогонов разрешается независимо для каждой строки и не меняет логическое значение поля UTF-16, строку PDF или выравнивание текста

Логический индекс может занимать две разные визуальные позиции на границе смешанного направления, поэтому VisualCaretPosition разрешает неоднозначность повторного перемещения через эту границу

Пример

var
  Session: TPDFlibFormSession;
  Selection: TPDFlibFormSelection;
begin
  Session := TPDFlibFormSession.Create(PDF);
  try
    if Session.FocusAt(PageNumber, MouseX, MouseY) = 1 then
      Session.FocusNext(False, True);
    if Session.BeginEdit(Session.FocusedFieldIndex) = 1 then
    begin
      Session.SetEditValue('A' + WideChar($D83D) + WideChar($DE00) + 'B');
      Session.SetSelectionRange(1, 2, fsuUnicodeCodePoint);
      Session.GetSelectionRange(fsuUTF16CodeUnit, Selection);
      Session.SetTextDirection(ftdAuto);
      Session.MoveVisualCaret(True, True);
      Session.PasteText('replacement');
      if Session.CanUndoEdit then
        Session.UndoEdit;
      if Session.CanRedoEdit then
        Session.RedoEdit;
      Session.CommitEdit;
    end;
  finally
    Session.Free;
  end;
end;

См. также

SetTextDirection, GetVisualCaretOrder, MoveVisualCaret, TPDFlibFormTextDirection, DispatchInputEvent, TPDFlibFormInputEvent, TPDFlibFormInputResult, UndoEdit, RedoEdit, ClearEditHistory, ReplaceSelection, CutSelection, PasteText, TPDFlibFormEditKind, SetSelectionRange, GetSelectionRange, ExecuteFormFieldScript, TPDFlibActionInfo