TPDFlibFormSession

Formularze, interakcja, typy danych

Opis

Prowadzi testy trafień AcroForm, nawigację klawiaturą, fokus, wartość edycji i stan zaznaczenia tekstu bez zależności od frameworka GUI

Dołączona instancja TPDFlib pozostaje własnością wywołującego i musi przeżyć sesję

Przejścia fokusa eksponują akcje Widget /Fo i /Bl jako typowane zwrotne wywołania gospodarza przez OnAction

Prostokąty stron używają wizualnego CropBox po obrocie strony w bieżących jednostkach miary biblioteki, z początkiem w wizualnym lewym górnym rogu

Ukierunkowane zaznaczenia zatrzymują niezależne pozycje kotwicy i kursora i mogą być ustawiane albo odpytywane w jednostkach kodowych UTF-16, punktach kodowych Unicode albo klastrach rozszerzonych grafemów

Edycje dwukierunkowe zatrzymują logiczną kolejność wartości pola, rozwiązując per-liniowo wizualne sloty kursora z poziomów zagnieżdżenia, więc fizyczny ruch Lewo i Prawo podąża za tekstem mieszanym od lewej do prawej i od prawej do lewej

Zamiany zaznaczenia wyzwalają /K do gospodarza, eksponują wybrany i zastępczy tekst przez OnTextEdit, wymuszają /MaxLen na pełnych granicach grafemów i zwijają zaznaczenie po jednej zaakceptowanej edycji

Każda aktywna edycja trzyma ograniczoną historię delty, która przywraca wartość tymczasową, wartość wyświetlaną i ukierunkowane zaznaczenie bez ponownego wyzwalania akcji formularza albo zwrotnych wywołań edycji gospodarza

DispatchInputEvent przelicza neutralne platformowo rekordy wskaźnika, kółka, klawiszy nazwanych i tekstu złożonego na obuzdane akcje Widget, przejścia fokusa, edycję bezpieczną dla grafemów, aktywację przycisków i nawigację wyborem

Sesja zatrzymuje tożsamość Widgetów, na których weszło i które wciśnięto, więc /E, /X, /D i /U przestrzegają kolejności wyzwalaczy PDF nawet przez przechwycenie wskaźnika i anulowanie

Zatwierdzenia wyzwalają akcje /V i /F, wykonują swój obsługiwany ograniczony podzbiór JavaScript przed zmianą dokumentu i zatrzymują aktywną edycję, gdy walidacja, formatowanie albo zwrotne wywołanie gospodarza odrzuci transakcję

Zwalidowana surowa wartość jest zapisywana w polu, podczas gdy DisplayValue i wygenerowany wygląd Widgeta zatrzymują każdy wynik formatowania

Deklaracja

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;

Metody

CreateTworzy sesję podłączoną do instancji biblioteki należącej do wywołującego
AttachLibraryResetuje cały stan przejściowy i podłącza inną instancję biblioteki należącą do wywołującego albo nil
ResetCzyści stan fokusu, edycji i zaznaczenia bez zmiany wartości pól ani wywoływania akcji
FocusFieldZatwierdza albo anuluje bieżącą edycję, wysyła /Bl dla poprzedniego widżetu, a następnie wysyła /Fo dla żądanego widocznego widżetu
GetFieldPageRectZwraca prostokąt widocznego widżetu w obróconych wizualnych współrzędnych CropBox bez zmiany wybranej strony
HitTestZwraca najwyższy widoczny widżet w wizualnym punkcie strony, traktując dalsze wpisy tablicy /Annots strony jako trafienie najbardziej z przodu
GetTabSequenceZwraca widoczne widżety na stronach w kolejności stron i stosuje semantykę /Tabs /R, /C, /S, PDF 2.0 /A i /W, rotację strony oraz ViewerPreferences /Direction; brakująca albo nieprawidłowa wartość /Tabs używa kolejności tablicy adnotacji
FocusAtWykonuje test trafienia wizualnego punktu strony i ustawia fokus zwróconego widżetu przez normalną ścieżkę zatwierdzenia, utraty fokusu i akcji fokusu
FocusNextPrzechodzi naprzód albo wstecz przez wyliczoną kolejność tabulacji z opcjonalnym zawijaniem i normalnymi regułami przejścia fokusu
BlurZatwierdza albo anuluje bieżącą edycję i wysyła /Bl przed usunięciem fokusu
BeginEditUstawia fokus edytowalnego pola tekstowego albo listy wyboru i wykonuje migawkę jego wartości pierwotnej
SetEditValueAktualizuje wartość przejściową i wymusza skonfigurowaną maksymalną długość pola tekstowego bez dzielenia rozszerzonego klastra grafemów
SetSelectionPrzycina i zapisuje zakres zaznaczenia UTF-16 liczony od zera w wartości przejściowej
SetSelectionRangePrzycina ukierunkowane pozycje kotwicy i karetki w żądanej jednostce indeksu, przelicza je na wewnętrzny zakres UTF-16 i nigdy nie dzieli punktu kodowego ani klastra grafemów, gdy użyto którejkolwiek jednostki Unicode
GetSelectionRangeZwraca kotwicę, karetkę, znormalizowany początek i długość w żądanej jednostce indeksu wraz z pierwotnym kierunkiem
SetTextDirectionWybiera automatyczny, jawny od lewej do prawej albo jawny od prawej do lewej kierunek akapitu i unieważnia buforowaną wizualną kolejność karetki
GetVisualCaretOrderZwraca bezpieczne dla grafemów logiczne indeksy karetki w fizycznej kolejności od lewej do prawej, łącznie z odrębnymi podzielonymi gniazdami na granicach o mieszanych kierunkach
MoveVisualCaretPrzesuwa albo rozszerza ukierunkowane zaznaczenie o jedno fizyczne gniazdo wizualne i zwija istniejące zaznaczenia w kierunku żądanej fizycznej krawędzi
GetSelectedTextZwraca aktualnie zaznaczony tekst UTF-16 albo pusty łańcuch
ReplaceSelectionZamienia znormalizowane zaznaczenie w ramach jednej podlegającej wetu transakcji /K i OnTextEdit, a następnie zwija karetkę po zaakceptowanej zamianie
CutSelectionZwraca i usuwa zaznaczony tekst tą samą atomową ścieżką zamiany
PasteTextZamienia bieżące zaznaczenie na tekst schowka dostarczony przez wywołującego bez wprowadzania zależności od schowka platformy
CanUndoEditRaportuje, czy aktywna edycja ma wpis historii, który można odwrócić
CanRedoEditRaportuje, czy aktywna edycja ma odwrócony wpis historii, który można odtworzyć
UndoEditOdwraca ostatni zachowany wpis edycji i przywraca jego poprzednie ukierunkowane zaznaczenie
RedoEditOdtwarza kolejny zachowany wpis edycji i przywraca jego wynikowe ukierunkowane zaznaczenie
ClearEditHistoryOdrzuca historię cofania i ponawiania aktywnej edycji bez zmiany jej bieżącej wartości ani zaznaczenia
DispatchInputEventRozsyła jedno niezależne od platformy zdarzenie wskaźnika, kółka, klawisza albo tekstu komponowanego i zwraca wynikowy stan fokusu, podświetlenia, naciśnięcia, wartości i zaznaczenia
CommitEditWaliduje i formatuje kandydata przed zapisaniem jego surowej wartości, odświeża sformatowany wygląd, a następnie wywołuje OnValueChanged
CancelEditOdrzuca wartość przejściową i zaznaczenie bez zmiany pola

Właściwości stanu

LibraryInstanceBieżąca instancja TPDFlib niebędąca własnością sesji
FocusedFieldIndexIndeks pola objętego fokusem albo tymczasowego widżetu, albo zero, gdy żaden widżet nie ma fokusu
EditingFieldIndexEdytowane bazowe pole tekstowe albo lista wyboru, albo zero, gdy żadna edycja nie jest aktywna
OriginalValueWartość pola przechwycona przez BeginEdit
EditValueBieżąca wartość przejściowa
DisplayValueBieżąca wartość edycji albo sformatowana wartość wyświetlana wytworzona przez ostatnie udane zatwierdzenie
SelectionStartPoczątkowy indeks UTF-16 liczony od zera
SelectionLengthDługość zaznaczenia w UTF-16
SelectionAnchorPozycja kotwicy UTF-16 liczona od zera, pozostająca nieruchoma, podczas gdy karetka rozszerza ukierunkowane zaznaczenie
SelectionCaretRuchoma krawędź ukierunkowanego zaznaczenia w UTF-16 liczona od zera
TextDirectionSkonfigurowany kierunek, domyślnie ftdAuto i zachowywany między edycjami w sesji
ResolvedTextDirectionKierunek jawny albo kierunek automatyczny wybrany z pierwszego mocnego znaku wartości aktywnej edycji
VisualCaretPositionBieżące gniazdo w buforowanej fizycznej kolejności karetki albo -1, gdy żaden wizualny ruch nie wybrał gniazda
MaxUndoStepsMaksymalna liczba zachowanych wpisów historii edycji od 0 do 10000; domyślnie 1000, a zero wyłącza rejestrowanie
UndoEditCountLiczba zachowanych wpisów aktualnie dostępnych dla UndoEdit
RedoEditCountLiczba zachowanych wpisów aktualnie dostępnych dla RedoEdit
ModifiedTrue, gdy EditValue różni się od OriginalValue
HoveredFieldIndexWidżet z aktualnie aktywnym stanem wejścia wskaźnika, albo zero
PressedFieldIndexWidżet zachowujący przechwytywanie głównego przycisku wskaźnika do pasującego zwolnienia albo anulowania wskaźnika, albo zero

Zdarzenia

OnActionOtrzymuje typowany TPDFlibActionInfo dla dostępnych akcji fokusu, utraty fokusu, klawisza, walidacji i formatowania; ustaw Allow na False, aby zawetować oczekującą operację
OnFocusChangedRaportuje każde zakończone przejście fokusu, w tym przejścia do zera po zawetowaniu nowej akcji fokusu
OnValueChangedRaportuje pomyślnie zatwierdzoną zmianę wartości po zaktualizowaniu pola i jego nieaktualnych wyglądów
OnTextEditOtrzymuje rodzaj edycji, zaznaczenie UTF-16, zaznaczony tekst i modyfikowalną zamianę przed zmianą wartości przejściowej; ustaw Allow na False dla atomowego odrzucenia

Wartość zwracana

Funkcje zmieniające stan zwracają 1 w razie powodzenia i 0, gdy żądanie jest nieprawidłowe, ponownie wchodzące, zawetowane albo nie może zostać zatwierdzone; HitTest zwraca indeks pola albo tymczasowego widżetu, a GetTabSequence liczbę wpisów

Jednostki wyboru

fsuUTF16CodeUnit zachowuje przestarzałą umowę indeksowania WideString o podstawie zero, w tym pozycje wewnątrz pary surrogatów, gdy są jawnie żądane

fsuUnicodeCodePoint liczy ważną parę surrogatów jako jeden uzupełniający punkt kodowy i traktuje niesparowany surrogat jako jeden samodzielny punkt kodowy

fsuGraphemeCluster liczy kompletne klastry rozszerzonych grafemów, więc sekwencje łączące i połączone emoji pozostają niepodzielne

Tabele granic Unicode są podręczne dla bieżącej wartości edycji i unieważniane przy zmianie tej wartości

Nawigacja dwukierunkowa

ftdAuto używa pierwszego mocnego znaku i domyślnie przyjmuje od lewej do prawej, gdy edycja nie ma mocnego znaku kierunkowego

Wizualna kolejność odcinków jest rozwiązywana niezależnie dla każdej linii i nie zmienia logicznej wartości pola UTF-16, ciągu PDF ani wyrównania tekstu

Indeks logiczny może zajmować dwa różne wizualne sloty na granicy mieszanych kierunków, więc VisualCaretPosition rozróżnia powtarzany ruch przez tę granicę

Przykład

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;

Zobacz również

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