[Example] Document structure as a tree
Posted: Mon Jan 04, 2010 9:18 pm
Update: the code in the message is for TRichView 17.2 and older. For TRichView 17.3 and newer, see viewtopic.php?f=3&t=3627&p=34717#p34717
The code below shows a document structure in TreeView.
The first level of this structure is "Document".
The second level: paragraphs (in TRichView, paragraphs are not represented as objects; items simply have "new paragraph" flags; but for the convenience of displaying a structure, paragraphs are shown as a structure level). For paragraphs, the following properties are shown:
- Outline level (if positive, it is named 'Heading level N' instead of 'Paragraph')
- ParaNo (index of paragraph style)
- page break (if this paragraph has "page break before" flag)
- text flow properties (clear left/right/both, if specified)
The third level: items. For text items, their text is shown. For non-text items, class of their items is shown. Index of text style/item type (StyleNo) is shown.
If the item is a hyperlink, or it has a non-empty tag, this information is shown.
If some item starts a line break inside a paragraph, "line break" is added before this item.
The fourth level: checkpoint (if the item has it). A name is displayed for the checkpoint.
Special cases:
1) Tables. For tables, the fourth level is rows, the fifth level is cells. Each cell is a document with its own structure levels.
2) Footnotes and endnotes. For notes, the fourth level is "Note text". This is a document with its own structure levels.
3) List markers. Information about list marker is shown in the fourth level.
How to use:
Updates:
2011-Mar-31: displaying paragraph outline level
2011-Oct-2: for compatibility with TRichView 13.4
The code below shows a document structure in TreeView.
The first level of this structure is "Document".
The second level: paragraphs (in TRichView, paragraphs are not represented as objects; items simply have "new paragraph" flags; but for the convenience of displaying a structure, paragraphs are shown as a structure level). For paragraphs, the following properties are shown:
- Outline level (if positive, it is named 'Heading level N' instead of 'Paragraph')
- ParaNo (index of paragraph style)
- page break (if this paragraph has "page break before" flag)
- text flow properties (clear left/right/both, if specified)
The third level: items. For text items, their text is shown. For non-text items, class of their items is shown. Index of text style/item type (StyleNo) is shown.
If the item is a hyperlink, or it has a non-empty tag, this information is shown.
If some item starts a line break inside a paragraph, "line break" is added before this item.
The fourth level: checkpoint (if the item has it). A name is displayed for the checkpoint.
Special cases:
1) Tables. For tables, the fourth level is rows, the fifth level is cells. Each cell is a document with its own structure levels.
2) Footnotes and endnotes. For notes, the fourth level is "Note text". This is a document with its own structure levels.
3) List markers. Information about list marker is shown in the fourth level.
Code: Select all
procedure ShowStructure(RVData: TCustomRVData; Node: TTreeNode);
var i, StyleNo: Integer;
ParaNode, ItemNode: TTreeNode;
function GetExtraBreakProps(i: Integer): String;
begin
if RVData.PageBreaksBeforeItems[i] then begin
Result := '; page break';
exit;
end;
if RVData.ClearLeft[i] then
if RVData.ClearRight[i] then
Result := '; clear both'
else
Result := '; clear left'
else
if RVData.ClearRight[i] then
Result := '; clear right'
else
Result := '';
end;
function GetExtraItemString(i: Integer): String;
begin
Result := '';
if RVData.GetItem(i).GetBoolValueEx(rvbpJump, RVData.GetRVStyle) then
Result := '; hyperlink';
if RVData.GetItemTag(i)<>'' then
Result := Result+ '; tag: "'+RVData.GetItemTag(i)+'"';
end;
procedure AddCheckpoint(i: Integer);
var CPTag: TRVTag;
CPName: String;
CPRE: Boolean;
begin
if RVData.GetItemCheckpoint(i)<>nil then begin
RVData.GetCheckpointInfo(RVData.GetItemCheckpoint(i), CPTag, CPName, CPRE);
Node.Owner.AddChild(ItemNode, Format('Checkpoint "%s"',
[CPName]));
end;
end;
procedure AddTableInfo(i: Integer);
var r, c: Integer;
table: TRVTableItemInfo;
RowNode, CellNode: TTreeNode;
begin
table := TRVTableItemInfo(RVData.GetItem(i));
for r := 0 to table.RowCount-1 do begin
RowNode := Node.Owner.AddChild(ItemNode, Format('Row %d', [r]));
for c := 0 to table.ColCount-1 do begin
if table.Cells[r,c]<>nil then begin
CellNode := Node.Owner.AddChild(RowNode, Format('Cell %d', [c]));
ShowStructure(table.Cells[r,c].GetRVData, CellNode);
end;
end;
end
end;
procedure AddListMarkerInfo(i: Integer);
var ListNo, Level, StartFrom: Integer;
UseStartFrom: Boolean;
s: String;
begin
RVData.GetListMarkerInfo(i, ListNo, Level, StartFrom, UseStartFrom);
s := Format('ListNo=%d, Level=%d',[ListNo, Level]);
if UseStartFrom then
s := s+Format(', start from %d', [StartFrom]);
Node.Owner.AddChild(ItemNode, s);
end;
function GetParaCaption(i: Integer): String;
var Level: Integer;
begin
Level := RVData.GetRVStyle.ParaStyles[RVData.GetItemPara(i)].OutlineLevel;
if Level<=0 then
Result := 'Paragraph'
else
Result := Format('Heading level %d', [Level]);
end;
begin
ParaNode := nil;
for i := 0 to RVData.ItemCount-1 do begin
if RVData.IsParaStart(i) then
ParaNode := Node.Owner.AddChild(Node, Format('%s, ParaNo=%d%s',
[GetParaCaption(i), RVData.GetItemPara(i), GetExtraBreakProps(i)]))
else if RVData.IsFromNewLine(i) then
Node.Owner.AddChild(ParaNode, Format('Line break%s',
[GetExtraBreakProps(i)]));
StyleNo := RVData.GetItemStyle(i);
if StyleNo>=0 then
ItemNode := Node.Owner.AddChild(ParaNode, Format('Text "%s", StyleNo=%d%s',
[RVData.GetItemText(i), StyleNo, GetExtraItemString(i)]))
else begin
ItemNode := Node.Owner.AddChild(ParaNode, Format('%s [StyleNo=%d]%s',
[RVData.GetItem(i).ClassName, StyleNo, GetExtraItemString(i)]));
if RVData.GetItem(i) is TRVTableItemInfo then
AddTableInfo(i)
else if RVData.GetItem(i) is TCustomRVNoteItemInfo then
ShowStructure(TCustomRVNoteItemInfo(RVData.GetItem(i)).Document,
Node.Owner.AddChild(ItemNode, 'Note text'))
else if RVData.GetItem(i) is TRVMarkerItemInfo then
AddListMarkerInfo(i);
end;
AddCheckpoint(i);
end;
end;
Code: Select all
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
TreeView1.Items.AddChildFirst(nil, 'Document');
ShowStructure(RichViewEdit1.RVData, TreeView1.Items[0]);
TreeView1.Items.EndUpdate;
2011-Mar-31: displaying paragraph outline level
2011-Oct-2: for compatibility with TRichView 13.4