📄 ucatexpert.pas
字号:
{Called when the users starts to drag the splitter.
~param Sender the sender of the event, ~[link PanelSplitter]
~param Button the button the user clicked with
~param Shift state of the extra keys Shift, Control and Alt
~param X, Y position of the click }
procedure TFormCatExpert.PanelSplitterMouseDown(Sender: TObject;
Button: TMouseButton;
Shift: TShiftState;
X, Y: Integer);
begin
PanelSplitter.Tag := Y; //save position in the splitter
end;
{Called when the users is dragging the splitter.
~param Sender the sender of the event, ~[link PanelSplitter]
~param Shift state of the extra keys Shift, Control and Alt and the buttons
the user holds while moving
~param X, Y position of the click }
procedure TFormCatExpert.PanelSplitterMouseMove(Sender: TObject;
Shift: TShiftState;
X, Y: Integer);
begin
if Mouse.Capture = PanelSplitter //currently dragging the splitter?
{$IFNDEF LINUX}
.Handle
{$ENDIF}
then
//change the size of both sides
ResizeTreeView(TreeView.Height + Y - PanelSplitter.Tag);
end;
{Called via a timer after the form has been resized.
~param Sender the sender of the event, ~[link TimerResize] }
procedure TFormCatExpert.TimerResizeTimer(Sender: TObject);
begin
TimerResize.Enabled := False; //this is a one-shot timer
ResizeTreeView(TreeView.Height); //now check the size of the tree view
end;
{Resizes the tree view and the rich edit. This can either be caused by the user
by the dragging the splitter control or by a resize of the form or by loading
the initialization settings.
~param Height the new height to be set for the tree view. }
procedure TFormCatExpert.ResizeTreeView(Height: Integer);
var Top :Integer; //new vertical position of RichEdit
begin
//set the new height
TreeView.Height := Max(40, Min(StatusBar.Top - TreeView.Top -
PanelSplitter.Height - 9 + 2,
Height));
//calculate new position of the rich edit and set it and its new size
Top := TreeView.Height + TreeView.Top + 2;
RichEditHelpText.SetBounds(RichEditHelpText.Left, Top,
RichEditHelpText.Width,
StatusBar.Top - Top - 9);
PanelSplitter.Top := Top - 3; //adjust position of the splitter
if RichEditHelpText.Height <= 0 then
RichEditHelpText.Text := 'Help text was disabled, select an option to get the text.';
end;
{Shows the help text for the option.
~param OptionIndex the index of the option itself
~param HelpOptionIndex the value of the
~[link TOptionDescription.HelpOptionIndex] attribute of
the option to indicate the the option whose help text
should be used
~param OptionName the name of the option }
procedure TFormCatExpert.ShowHelpText(OptionIndex, HelpOptionIndex: Cardinal;
const OptionName: String);
var Descr :TOptionDescription; //description of the other option
AnchorName :String; //the name of the topic
begin
if RichEditHelpText.Height > 0 then //only get text if visible
//not a real topic available?
if (HelpOptionIndex = HelpOptionIndexShowMainTopic) or
(HelpOptionIndex = HelpOptionIndexNoHelp) then
begin
//just show the message
RichEditHelpText.Text := 'No help text available for this option.'
end
else
begin
//help text of another option should be used?
if HelpOptionIndex <> HelpOptionIndexShowThisTopic then
begin
Dec(HelpOptionIndex); //get its index
//get the other option's description
FOptions.Description(HelpOptionIndex, Descr);
//and its anchor
AnchorName := FOptions.Topic(HelpOptionIndex) + '.' + Descr.Name;
end
else
//get the anchor of the option
AnchorName := FOptions.Topic(OptionIndex) + '.' + OptionName;
ShowAnchorHelpText(AnchorName); //extract and show the help text
end;
end;
{Shows the help text of an option at the anchor.
~param AnchorName the name of the anchor to extract the help text at }
procedure TFormCatExpert.ShowAnchorHelpText(const AnchorName: String);
//the file name of the HTML file with the help texts of the options
const DefaultFileName = 'Documentation\options.html';
var FileName :String; //the file name of the HTML file
Content :String; //the content of the HTML file
StartPos :Integer; //position of the help text
EndPos :Integer; //end position of some text
OptionTitle :String; //the title of the help text
// HelpText :String; //the help text
begin
FileName := ExtractFilePath(ParamStr(0)) + DefaultFileName;
//
if not FileExists(FileName) then
FileName := ExtractFilePath(ParamStr(0)) + 'z_html\options.html';
//
if not FileExists(FileName) then
//just show the message
RichEditHelpText.Text := 'File with the help texts could not be found:'#10 +
DefaultFileName
else
//try to read the content of the file
if not UFilePaths.ReadFileContent(FileName, Content) then
//if that fails, just show the message
RichEditHelpText.Text := 'The content of the file with the help texts could not be read:'#10 +
DefaultFileName
else
begin
StartPos := Pos('<dt><a name="' + AnchorName + '">', Content);
if StartPos = 0 then
//if anchor can not be found, just show the message
RichEditHelpText.Text := 'The help text for the option could not be found in the file with the help texts:'#10 +
DefaultFileName
else
begin
//search the end of the help text
EndPos := SearchString('</dd>', Content,
StartPos + 15 + Length(AnchorName));
if EndPos = 0 then
EndPos := Length(Content);
//extract the title and the help text
Content := Copy(Content, StartPos + 15 + Length(AnchorName),
EndPos - StartPos - 15 - Length(AnchorName));
//extract the title of the help text
StartPos := Pos('</dt>', Content);
if StartPos = 0 then
StartPos := Length(Content);
OptionTitle := Copy(Content, 1, StartPos - 1);
//remove the anchor end tah
StartPos := Pos('</a>', OptionTitle);
if StartPos <> 0 then
Delete(OptionTitle, StartPos, 4);
//remove the title and its tags
EndPos := SearchString('<dd>', Content, StartPos + 5);
if EndPos = 0 then
Delete(Content, 1, StartPos)
else
Delete(Content, 1, EndPos + 3);
//clear the rich edit and add the title bigger and centered
RichEditHelpText.Clear;
RichEditHelpText.Paragraph.Alignment := taCenter;
RichEditHelpText.SelAttributes.Size := Round(Font.Size * 1.33);
RichEditHelpText.SelAttributes.Style := [fsBold];
AppendHTMLSnippetToRichEdit(OptionTitle, RichEditHelpText);
//end the line
RichEditHelpText.Lines.Append('');
//restore original font
RichEditHelpText.Paragraph.Alignment := taLeftJustify;
RichEditHelpText.SelAttributes.Size := Font.Size;
RichEditHelpText.SelAttributes.Style := [];
//add an empty line
RichEditHelpText.Lines.Append('');
//and add the HTML snippet
AppendHTMLSnippetToRichEdit(Content, RichEditHelpText);
end;
end;
end;
{$ENDIF}
{Fills the combo box with all topics of the options. }
procedure TFormCatExpert.FillComboBox;
var i :Integer; //counter through options
LastTopic :String; //the last topic
begin
if FOptions.Count > 0 then //some options available?
begin
LastTopic := FOptions.Topic(0); //get first topic
for i := 1 to FOptions.Count - 1 do //for each other option
if FOptions.Topic(i) <> LastTopic then //a new topic?
begin
//prepend the last topic and the number of its options to the list
ComboBoxTopics.Items.AddObject(LastTopic, TObject(i));
LastTopic := FOptions.Topic(i); //save new topic
end;
ComboBoxTopics.Items.AddObject(LastTopic, TObject(FOptions.Count));
end;
ComboBoxTopics.Visible := ComboBoxTopics.Items.Count > 1;
RadioGroupShowOptions.Visible := ComboBoxTopics.Visible;
end;
{Fills the list with all options.
~param First index of the first option show
~param Last index + 1 of the last option show/the first option not to show }
procedure TFormCatExpert.FillTreeView(First, Last: Integer);
{Returns the node to add the node of the option to, if it does not exist it is
created.
~param Category the string of category
~result the node to add the node of the option to }
function GetCreateCategoryNode(Category: String): TTreeNode;
var Dot :Integer; //position of the next dot in the category string
MainCat :String; //the next category in Category
Next :TTreeNode; //counter through the nodes
begin
if Category = '' then //no category defined?
Result := nil //add directly to the root
else
begin
Result := TreeView.Items.GetFirstNode; //get the first node
Next := Result; //add so far to it
repeat
Dot := Pos('.', Category); //get position of end of the first category
if Dot = 0 then //extract first category
begin
MainCat := Category;
Category := '';
end
else
begin
MainCat := Copy(Category, 1, Dot - 1);
Delete(Category, 1, Dot);
end;
if not Assigned(Result) then //no node unter this node?
begin
if not Assigned(Next) then //tree is empty so far?
Result := TreeView.Items.Add(nil, MainCat) //add first node
else
Result := TreeView.Items.AddChild(Next, MainCat); //add under the node
Result.ImageIndex := ord(iiClosed); //category is closed so far
Result.SelectedIndex := ord(iiClosed);
end
else
begin
Next := Result.GetNextSibling; //get the next node
//search the category on this level (or position to insert)
while (TImageIndex(Result.ImageIndex) <> iiOption) and
(CompareText(Result.Text, MainCat) < 0) and
Assigned(Next) do
begin
Result := Next; //next node on the same level
Next := Result.GetNextSibling;
end;
//category not found?
if (TImageIndex(Result.ImageIndex) = iiOption) or
(CompareText(Result.Text, MainCat) > 0) then
Result := TreeView.Items.Insert(Result, MainCat) //insert before node
else
if CompareText(Result.Text, MainCat) < 0 then //not found?
begin
Assert(not Assigned(Next));
Result := TreeView.Items.Add(Result, MainCat); //add behind node
end;
Result.ImageIndex := ord(iiClosed); //category is closed so far
Result.SelectedIndex := ord(iiClosed);
end; //else not assigned(Result)
if Category <> '' then //other categories?
begin
Next := Result; //descend one level
Result := Result.GetFirstChild;
end;
until Category = ''; //all categories processed?
end; //else Category = ''
end;
{Adds the option as a node under the parent node.
~param Parent the node to add the node of the option to
~param Name the name of the option
~param Value the value of the option
~param Index the index of the option }
procedure AddOption(Parent: TTreeNode; Name, Value: String; Index: Cardinal);
{If the name of the option in the text smaller than the name of the current
option is.
~param Text the text of a node of an option
~result if the name of the text is smaller than the name of the current
option and the option should be behind it }
function CompareSkip(Text: String): Boolean;
var i :Integer; //index of the separating ": "
begin
i := Pos(': ', Text);
if i <> 0 then //is separated?
Text := Copy(Text, 1, i - 1); //extract the name
Result := CompareText(Text, Name) < 0; //name of node is smaller?
end;
var Child :TTreeNode; //the new node of the option
begin
Value := Name + ': ' + Value; //get the text for the node
if not Assigned(Parent) then //get the first node on the level
Child := TreeView.Items.GetFirstNode
else
Child := Parent.GetFirstChild;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -