Items' Checkpoints in TRichView

<< Click to display table of contents >>

Items' Checkpoints in TRichView

Checkpoints are...

Each item can have an associated "checkpoint" – an invisible label that you can use for jumping to the specified part of document. Other word-processing tools call similar objects "bookmarks" or "anchors".

Checkpoint has:

name;

tag (just like any RichView items tags)

RaiseEvent flag; if RaiseEvent=True then TRichView generates OnCheckpointVisible  event when this checkpoint appears in the field of view (usually as a result of scrolling); this feature only works for TRichView, and does not work for TRichViewEdit (in this version).

Limitations:

checkpoint names and tags must not contain #0, #1 and #2 characters; failing to follow this rule will cause problems in saving documents in RichView Format;

the following names are reserved: '_footnoteN', '_endnoteN', '_sidenoteN', where N is a number.

Drawing checkpoints

You can set the option to make checkpoints visible: include rvoShowCheckpoints in RichView.Options. By default, checkpoints are shown as dotted horizontal lines with a small circle in the top left corner of the associated item. Displaying checkpoints is useful in editing mode.

Checkpoints colors:

RichView.Style.CheckpointColor for "normal" checkpoints (clGreen by default)

RichView.Style.CheckpointEvColor for checkpoints with RaiseEvent=True (clLime by default)

You can create your own procedure for drawing checkpoints, see TRVStyle.OnDrawCheckpoint.

Using checkpoints

A checkpoint is usually used to get its vertical coordinate (relative to the top of the document area) and scrolling the document so that the item associated with this checkpoint becomes visible. There are some more interesting applications for checkpoints.

Adding checkpoints in the document

You can add checkpoint at the end of the document using AddCheckpoint method.

When you add a new item to the end of the document, the last added checkpoint becomes associated with this item. (So, TRichView can contain any number of checkpoints associated with items and only one checkpoint at the end of the document).

You can modify the checkpoint by SetCheckpointInfo method, and remove it by RemoveCheckpoint.

The rest of methods can be separated into two groups:

1.Methods returning information about some checkpoint. These methods return a value of TCheckpointData class.

2.Methods extracting checkpoint properties from the TCheckpointData value.

Methods and events of the first group (obtaining TCheckpointData):

TCheckpointData is a pointer. If these methods return nil, it means that there is no such checkpoint, item has no associated checkpoint, etc.

GetFirstCheckpoint, GetNextCheckpoint(CheckpointData), GetLastCheckpoint, GetPrevCheckpoint(CheckpointData) allow you to obtain a list of all checkpoints in the document (except for checkpoints in table cells, see below);

GetItemCheckpoint(ItemNo) returns the checkpoint associated with the specified item;

GetCheckpointByNo(No)  returns the checkpoint with the specified index;

FindCheckpointByName(Name) returns the first checkpoint having the specified Name;

FindCheckpointByTag(Tag) returns the first checkpoint having the specified Tag;

event OnCheckpointVisible (Sender: TRichView; CheckpointData: TCheckpointData); this event is generated when:

oRichView.CPEventKind = cpeWhenVisible and some checkpoint (with RaiseEvent=True) becomes visible (example of application: you can mark pictures in TRichView with checkpoints; when this picture becomes visible you can display information about it in a separate window)

oRichView.CPEventKind = cpeAsSectionStart; in this mode it's guaranteed that the last event is generated for visible checkpoint or for the nearest checkpoint above the visible area (example of application: you can mark beginnings of chapters of your document with checkpoints, create a table of contents in ListBox (one listbox item = one chapter = one "RaiseEvent" checkpoint); if you select listbox item associated with the last raised checkpoint, the list box will always have name of the chapter in the field of view highlighted)

Methods of the second group (extracting information from TCheckpointData):

GetCheckpointInfo(CheckpointData, Tag, Name, RaiseEvent) returns Tag, Name and "RaiseEvent" flag of checkpoint;

GetCheckpointXY(CheckpointData, X,Y), GetCheckpointYEx(CheckpointData): TRVCoord obtaining information about coordinates of checkpoint (Y is the most useful; you can pass this Y to RichView.ScrollTo method);

GetCheckpointItemNo(CheckpointData) : Integer returns the index of the associated item; it can return -1 for checkpoint in the end of document (no associated item);

GetCheckpointNo(CheckpointData): Integer returns the index of the checkpoint;

Methods belonging to the both groups:

GetCheckpointY(no): TRVCoord equivalent to GetCheckpointYEx(GetCheckpointByNo(No));

Methods of editor

The first group of methods contains editing-style analogs of SetCheckpointInfo and RemoveCheckpoint:

SetCheckpointInfoEd adds checkpoint for the specified item, as an editing operation;

RemoveCheckpointEd deletes checkpoint for the specified item, as an editing operation.

The second group contains methods working with the item at the position of caret (if the caret is between items, they work with the item to the left):

GetCurrentCheckpoint returns checkpoint associated with the item at the caret position;

SetCurrentCheckpointInfo adds/modifies checkpoint for the item at the caret position, as an editing operation;

RemoveCurrentCheckpoint deletes checkpoint for the item at the caret position, as an editing operation.

The third group contains methods working with the checkpoint at the position of caret:

InsertCheckpoint inserts checkpoint in the caret position (adds/modifies checkpoint for the item to the right; if the caret was in the middle of text item, the method preliminarily splits this item at the caret position), as an editing operation;

GetCheckpointAtCaret returns the checkpoint exactly at the caret position;

RemoveCheckpointAtCaret deletes the checkpoint exactly at the caret position, as an editing operation.

RTF, DocX, and HTML

In HTML, checkpoints are saved as anchors (<a name> tag). Either checkpoint name or checkpoint index can be used, see HTMLSaveProperties.UseCheckpointNames. Links to checkpoints must start with '#' character. When importing HTML, anchors are imported as checkpoints. Optionally, "id" attributes of tags can be imported as checkponts, see HTMLReadProperties.IDAsCheckpoints.

In RTF and DocX, checkpoints are saved as bookmarks (checkpoints names are used). When importing RTF or DocX, a bookmark start is read as checkpoint (bookmark name is written in checkpoint name). When reading RTF or DocX, links to bookmarks are converted to links started from '#'. When writing RTF or DocX, links started from '#' are written as links to bookmarks.

Example 1

Enumerating all checkpoints in the document (not including checkpoints in table cells). This method is very fast even for large documents, because all checkpoints are organized in a special list.

var Tag: TRVTag;

    Name: TRVUnicodeString;

    RaiseEvent: Boolean;

    CheckpointData: TCheckpointData;

begin

  CheckpointData := MyRichView.GetFirstCheckPoint;

  while CheckpointData<>nil do begin

    MyRichView.GetCheckpointInfo(CheckpointData,Tag,Name,RaiseEvent);

      // processing this checkpoint

    ...

    CheckpointData := MyRichView.GetNextCheckpoint(CheckpointData);

  end;

end;

 

Example 2

Enumerating all checkpoints in the document, including checkpoints in table cells

procedure EnumCheckpoints(RVData: TCustomRVData);

var i,r,c: Integer;

  table: TRVTableItemInfo;

  Tag: TRVTag;

  Name: TRVUnicodeString;

  RaiseEvent: Boolean;

  CheckpointData: TCheckpointData;

begin

  for i := 0 to RVData.ItemsCount-1 do begin

    CheckpointData := RVData.GetItemCheckpoint(i);

    if CheckpointData<>nil then begin

      RVData.GetCheckpointInfo(CheckpointData,Tag,Name,RaiseEvent);

      // processing this checkpoint

      ...

    end;

    if RVData.GetItem(i) is TRVTableItemInfo then

    begin

      table := TRVTableItemInfo(RVData.GetItem(i));

      for r := 0 to table.RowCount-1 do

        for c := 0 to table.ColCount-1 do

          if table.Cells[r,c]<>nil then

            EnumCheckpoints(table.Cells[r,c].GetRVData);

    end;

  end;

end;

Call:

EnumCheckpoints(MyRichView.RVData);

 

In the second example, RVData.GetCheckpointXY returns checkpoint coordinates relative to the top left corner of this RVData (it may be left top corner of the cell). In order to get absolute coordinates of this checkpoint in the document (for MyRichView.ScrollTo), obtain the coordinates of top left corner of this RVData (TCustomRVFormattedData(RVData).GetOriginEx(X,Y)), relative coordinates of checkpoint (TCustomRVFormattedData(RVData).GetCheckpointXY(X,Y)), and sum them up

See also...

See also properties and events of TRVStyle:

CheckpointColor, CheckpointEvColor, OnDrawCheckpoint

See also properties of TRichView:

Options,.CPEventKind

See also events of TRichView:

OnCheckpointVisible

See also methods of TRichView:

AddCheckpoint, SetCheckpointInfo, RemoveCheckpointGetFirstCheckpoint, GetNextCheckpoint, GetItemCheckpoint, GetCheckpointByNo, FindCheckpointByName, FindCheckpointByTag, GetCheckpointInfo, GetCheckpointXY, GetCheckpointYEx, GetCheckpointItemNo, GetCheckpointNo, GetCheckpointY

See also methods of TRichViewEdit:

GetCurrentCheckpoint, SetCheckpointInfoEd, RemoveCheckpointEd