TPDFlibFormSession

フォーム、インタラクション、データ型

説明

GUIフレームワークに依存せずに、AcroFormのヒットテスト、キーボードナビゲーション、フォーカス、編集値、テキスト選択状態を維持します

アタッチされたTPDFlibインスタンスは呼び出し元所有のまま残り、セッションより長く生存する必要があります

フォーカス遷移はWidgetの/Foと/Blアクションを、型付きホストコールバックとしてOnAction経由で公開します

ページ矩形は、ページ回転後の視覚CropBoxをライブラリの現在の測定単位で使います。原点は視覚左上です

方向付き選択は独立したアンカーとキャレットの位置を保持し、UTF-16コードユニット、Unicodeコードポイント、拡張書素クラスタで設定・照会できます

双方向編集は論理的なフィールド値順を保ちつつ、埋め込みレベルから行ごとの視覚キャレットスロットを解決するため、物理的な左右移動は左から右と右から左が混在するテキストに従います

選択の置換は/Kをホストへディスパッチし、選択テキストと置換テキストをOnTextEditで公開し、完全な書素境界で/MaxLenを強制し、1回の受け入れられた編集の後に選択を折りたたみます

各アクティブ編集は、フォームアクションやホストの編集コールバックを再ディスパッチせずに一時値、表示値、方向付き選択を復元する、上限付きの差分履歴を保持します

DispatchInputEventは、プラットフォーム中立なポインター、ホイール、名前付きキー、合成テキストのレコードを、制約付きWidgetアクション、フォーカス遷移、書素セーフな編集、ボタンのアクティブ化、チョイスナビゲーションへ変換します

セッションは進入中と押下中のWidget識別を保持するため、/E、/X、/D、/UはポインターのキャプチャやキャンセルをまたいでもPDFトリガー順序に従います

コミットは/Vと/Fアクションをディスパッチし、ドキュメントを変更する前にサポートされる有界JavaScriptサブセットを実行し、検証・フォーマット・ホストコールバックがトランザクションを拒否した場合はアクティブな編集を保持します

検証済みの生の値はフィールドへ保存され、DisplayValueと生成されたWidget外観はフォーマットの結果を保持します

宣言

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現在の編集を確定またはキャンセルし、前の Widget に対して /Bl をディスパッチしてから、要求された可視 Widget に対して /Fo をディスパッチします
GetFieldPageRect選択されたページを変更せずに、回転後の視覚 CropBox 座標での可視 Widget 矩形を返します
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一時的な値内の 0 ベース UTF-16 選択範囲を制限して保存します
SetSelectionRange要求されたインデックス単位での方向付きアンカーとキャレット位置を制限し、内部の UTF-16 範囲へ変換します。Unicode 単位が使用された場合、コードポイントや書記素クラスタを決して分割しません
GetSelectionRange要求されたインデックス単位でのアンカー、キャレット、正規化された開始位置と長さを、元の方向とともに返します
SetTextDirection自動、明示的な左から右、明示的な右から左の段落方向を選択し、キャッシュされた視覚キャレット順序を無効化します
GetVisualCaretOrder混在方向の境界での個別の分割スロットを含め、物理的な左から右の順序での書記素セーフな論理キャレットインデックスを返します
MoveVisualCaret方向付き選択を 1 つの物理的な視覚スロットだけ移動または拡張し、既存の選択を要求された物理端へ折りたたみます
GetSelectedText現在選択されている UTF-16 テキストまたは空の文字列を返します
ReplaceSelection正規化された選択を、1 つの拒否可能な /K と OnTextEdit のトランザクションを通じて置き換え、受け入れられた置換の後にキャレットを折りたたみます
CutSelection同じアトミックな置換パスを通じて選択テキストを返して削除します
PasteTextプラットフォームのクリップボード依存を導入せずに、現在の選択を呼び出し側指定のクリップボードテキストで置き換えます
CanUndoEditアクティブな編集に取り消し可能な履歴エントリがあるかどうかを報告します
CanRedoEditアクティブな編集に再生可能な取り消し済み履歴エントリがあるかどうかを報告します
UndoEdit保持されている最新の編集を取り消し、その以前の方向付き選択を復元します
RedoEdit保持されている次の編集を再生し、その結果の方向付き選択を復元します
ClearEditHistory現在の値や選択を変更せずに、アクティブな編集の元に戻す/やり直し履歴を破棄します
DispatchInputEvent1 つのプラットフォーム中立のポインタ、ホイール、キー、合成テキストイベントをディスパッチし、結果のフォーカス、ホバー、押下、値、選択の状態を返します
CommitEdit生の値を保存する前に候補を検証して書式設定し、書式設定された外観を更新してから OnValueChanged を発生させます
CancelEditフィールドを変更せずに一時的な値と選択を破棄します

状態プロパティ

LibraryInstance現在の非所有の TPDFlib インスタンス
FocusedFieldIndexフォーカスされたフィールドまたは一時 Widget インデックス。Widget にフォーカスがない場合は 0
EditingFieldIndex編集中のベーステキストまたは選択肢フィールド。編集がアクティブでない場合は 0
OriginalValueBeginEdit がキャプチャしたフィールド値
EditValue現在一時的な値
DisplayValue現在の編集値、または最後に成功した確定が生成した書式設定済み表示値
SelectionStart0 ベースの UTF-16 開始インデックス
SelectionLengthUTF-16 選択長
SelectionAnchorキャレットが方向付き選択を拡張する間固定されたままの、0 ベース UTF-16 アンカー位置
SelectionCaret方向付き選択の移動端の 0 ベース UTF-16 位置
TextDirection構成された方向。既定は ftdAuto で、セッション内の編集をまたいで保持されます
ResolvedTextDirection明示的な方向、またはアクティブな編集値の最初の強い文字から選択された自動方向
VisualCaretPositionキャッシュされた物理キャレット順序での現在のスロット。視覚移動がスロットを選択していない場合は -1
MaxUndoSteps0 から 10000 までの保持される編集履歴エントリの最大数。既定は 1000 で、0 は記録を無効にします
UndoEditCount現在 UndoEdit で利用可能な保持済みエントリの数
RedoEditCount現在 RedoEdit で利用可能な保持済みエントリの数
ModifiedTrue が EditValue と異なる場合は OriginalValue
HoveredFieldIndex現在ポインタが入った状態がアクティブな Widget。なければ 0
PressedFieldIndex対応するアップまたはポインタのキャンセルまでプライマリポインタキャプチャを保持する Widget。なければ 0

イベント

OnAction利用可能なフォーカス、ブラー、キーストローク、検証、書式設定の各アクションに対して型付き TPDFlibActionInfo を受け取ります。Allow を False に設定すると保留中の操作を拒否できます
OnFocusChanged新しいフォーカスアクションが拒否された後のゼロへの遷移を含め、完了した各フォーカス遷移を報告します
OnValueChangedフィールドとその変更済み外観が更新された後の、正常に確定された値の変更を報告します
OnTextEdit一時的な値が変わる前に、編集種別、UTF-16 選択、選択テキスト、書き換え可能な置換を受け取ります。アトミックに拒否するには Allow を False に設定します

戻り値

状態を変更する関数は、成功時に 1 を返し、要求が不正、再入、拒否された、または確定できない場合は 0 を返します。HitTest はフィールドまたは一時 Widget インデックスを返し、GetTabSequence はエントリ数を返します

選択の単位

fsuUTF16CodeUnitは従来のゼロ始まりWideStringインデックス契約を保持します。明示的に要求された場合のサロゲートペア内部の位置も含みます

fsuUnicodeCodePointは有効なサロゲートペアを1つの補助コードポイントとして数え、ペアでないサロゲートは1つの独立したコードポイントとして扱います

fsuGraphemeClusterは完全な拡張書素クラスタを数えるため、結合シーケンスと結合絵文字は分割されません

Unicode境界テーブルは現在の編集値に対してキャッシュされ、その値が変わると無効化されます

双方向ナビゲーション

ftdAutoは最初の強い文字を使い、編集に強い方向文字がなければ左から右を既定とします

視覚ラン順は行ごとに独立して解決され、論理的なUTF-16フィールド値、PDF文字列、テキスト配置は変更しません

混合方向境界では1つの論理インデックスが2つの異なる視覚スロットを占め得るため、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