📄 udiagramform.pas
字号:
for i := 0 to TheClass.Children.Count - 1 do //also call with all sub-classes
AddRemoveClassAndDescendants(AddRemove, TRecordType(TheClass.Children[i]));
end;
{Calls the procedure for each implementing class and their descendants of the
interface or one of its descendants.
~param AddRemove the procedure to call for the classes, either
~[link FDiagram.Add] or ~[link FDiagram.Remove]
~param Interf the interface whose implementing classes should be used to
call the procedure with }
procedure TFormDiagram.AddRemoveClassesImplementingOrDescendants(
AddRemove: THandleAddRemoveDataProc;
Interf: TRecordType);
var i :Integer; //general counter
TheClass :TIdentifier; //the implementing classes
begin
for i := 0 to Interf.Implementing.Count - 1 do //for each implementing class
begin
TheClass := Interf.Implementing[i]; //get it
assert(TheClass is TRecordType);
//call the procedure with class
AddRemoveClassAndDescendants(AddRemove, TRecordType(TheClass));
end;
for i := 0 to Interf.Children.Count - 1 do //for each sub-interface
//call also with their implementing classes
AddRemoveClassesImplementingOrDescendants(AddRemove,
TRecordType(Interf.Children[i]));
end;
{Called for all used types in a class, calls the procedure for each class. The
type of the procedure is ~[link TForEachIdentTypeProc].
~param Ident the TIdentType-identifier of a type
~param parent the identifier that uses it directly
~param DoRemove boolean value assigned(DoRemove) whether the classes should be
removed instead of added }
procedure TFormDiagram.AddRemoveAssociatedClasses(Ident: TIdentType;
Parent: TIdentifier;
DoRemove: TIdentifier);
var TheType :TType; //the final type
begin
TheType := Ident.GetFinalType; //get the final type
if assigned(TheType) and (TheType is TRecordType) then //a record-like type?
//call the procedure with this record-like type
if assigned(DoRemove) then
FDiagram.Remove(TRecordType(TheType), nil)
else
FDiagram.Add(TRecordType(TheType), nil);
end;
{Deletes all boxes. The type of this function is ~[link TForEachBoxRecallFunc].
~param TheClass the class of the box, if it is not a file diagram
~param TheFile the file of the box, or the file of the class
~param Selected if the box is selected
~result what actions to take on the box or the enumeration, it should always be
removed }
function TFormDiagram.DeleteSelected(TheClass: TRecordType;
TheFile: TPascalFile;
Selected: Boolean): TBoxEnumerationActions;
begin
Result := [beaRemoveBox]; //remove the box
end;
{Toggles the selection-state of all boxes. The type of this function is
~[link TForEachBoxRecallFunc].
~param TheClass the class of the box, if it is not a file diagram
~param TheFile the file of the box, or the file of the class
~param Selected if the box is selected
~result what actions to take on the box or the enumeration, the selection state
is always set to not Selected }
function TFormDiagram.ToggleSelection(TheClass: TRecordType;
TheFile: TPascalFile;
Selected: Boolean): TBoxEnumerationActions;
begin
Result := [beaChangeSelection]; //change the selection state
if not Selected then //currently not selected
Include(Result, beaIsSelected); //let it be selected
end;
{Deletes the box of the class, if it is not declared in the interface of a
unit. The type of this function is ~[link TForEachBoxRecallFunc].
~param TheClass the class of the box, if it is not a file diagram
~param TheFile the file of the box, or the file of the class
~param Selected if the box is selected
~result what actions to take on the box or the enumeration, it is removed if
the class is not declared in the interface of a unit }
function TFormDiagram.DeletePrivateClasses(TheClass: TRecordType;
TheFile: TPascalFile;
Selected: Boolean): TBoxEnumerationActions;
begin
if TheClass.Scope = sImplementation then //not in the interface of a unit?
Result := [beaRemoveBox] //remove it
else
Result := []; //no action on this box
end;
{Executes the action ~[link FDirectoryAction] with the help of the list of
files in ~[link FActionFiles]. The type of this function is
~[link TForEachBoxRecallFunc].
~param TheClass the class of the box, if it is not a file diagram
~param TheFile the file of the box, or the file of the class
~param Selected if the box is selected
~result what actions to take on the box or the enumeration, it is removed if
the class is not declared in the interface of a unit }
function TFormDiagram.HandleAction(TheClass: TRecordType; TheFile: TPascalFile;
Selected: Boolean): TBoxEnumerationActions;
begin
assert(assigned(TheFile));
assert(FDirectoryAction in [ddaSelect, ddaRemove, ddaRemoveOthers]);
if FDirectoryAction = ddaSelect then //files/classes should be selected
begin
Result := [beaChangeSelection]; //change the selection state
if FActionFiles.IndexOf(TheFile) <> -1 then //is one of the files (or in it)
Include(Result, beaIsSelected); //let it be selected
end
else
if (FDirectoryAction = ddaRemoveOthers) = //has to be removed?
(FActionFiles.IndexOf(TheFile) = -1) then
Result := [beaRemoveBox] //remove the box
else
Result := []; //nothing to do
end;
{Updates the states of the buttons in the tool-bar. }
procedure TFormDiagram.UpdateButtons;
{Updates the state of the buttons in the tool-bar specific to class diagrams.
~param IsClass if it is a class diagram }
procedure SetClass(IsClass: Boolean);
begin
{
ToolButtonFileNamesInClasses.Visible := IsClass; //show the buttons only
ToolButtonAssociations.Visible := IsClass; //if it is a class diagram
ToolButtonScopePrivate.Visible := IsClass;
ToolButtonScopeProtected.Visible := IsClass;
ToolButtonScopePublic.Visible := IsClass;
ToolButtonScopePublished.Visible := IsClass;
ToolButtonScopeAutomated.Visible := IsClass;
ToolButtonMemberField.Visible := IsClass;
ToolButtonMemberProperty.Visible := IsClass;
ToolButtonMemberMethod.Visible := IsClass;
ToolButtonShowFunctionReturnType.Visible := IsClass;
ToolButtonShowMethodParameter.Visible := IsClass;
}
ToolBarClasses.Visible := IsClass and ControlBar.Visible;
if IsClass then //is a class diagram?
begin //set states of buttons
ToolButtonFileNamesInClasses.Down := FDiagram.ShowFileNameInClass;
ToolButtonAssociations.Down := FDiagram.ShowAssociations;
ToolButtonScopePrivate.Down := sPrivate in FDiagram.ShowScopes;
ToolButtonScopeProtected.Down := sProtected in FDiagram.ShowScopes;
ToolButtonScopePublic.Down := sPublic in FDiagram.ShowScopes;
ToolButtonScopePublished.Down := sPublished in FDiagram.ShowScopes;
ToolButtonScopeAutomated.Down := sAutomated in FDiagram.ShowScopes;
ToolButtonMemberField.Down := mkField in FDiagram.ShowMembers;
ToolButtonMemberProperty.Down := mkProperty in FDiagram.ShowMembers;
ToolButtonMemberMethod.Down := mkMethod in FDiagram.ShowMembers;
ToolButtonShowFunctionReturnType.Down := FDiagram.ShowReturnType;
ToolButtonShowMethodParameter.Down := FDiagram.ShowMethodParameters;
ToolButtonShowFunctionReturnType.Enabled := mkMethod in
FDiagram.ShowMembers;
ToolButtonShowMethodParameter.Enabled := mkMethod in FDiagram.ShowMembers;
end;
end;
{Updates the state of the buttons in the tool-bar specific to file diagrams.
~param IsFile if it is a file diagram }
procedure SetFile(IsFile: Boolean);
begin
{
ToolButtonUsingImplementation.Visible := IsFile; //show the buttons only
//if it is a file diagram
ToolButtonRecords.Visible := IsFile;
ToolButtonObjects.Visible := IsFile;
ToolButtonClasses.Visible := IsFile;
ToolButtonInterfaces.Visible := IsFile;
ToolButtonDispatchInterfaces.Visible := IsFile;
ToolButtonClassesNotInInterface.Visible := IsFile;
}
ToolBarFiles.Visible := IsFile and ControlBar.Visible;
if IsFile then //is a file diagram?
begin //set states of buttons
ToolButtonUsingImplementation.Down := FDiagram.ShowUsingImplementation;
ToolButtonRecords.Down := rkRecord in FDiagram.ShowClasses;
ToolButtonObjects.Down := rkObject in FDiagram.ShowClasses;
ToolButtonClasses.Down := rkClass in FDiagram.ShowClasses;
ToolButtonInterfaces.Down := rkInterface in FDiagram.ShowClasses;
ToolButtonDispatchInterfaces.Down := rkDispInterface in
FDiagram.ShowClasses;
ToolButtonClassesNotInInterface.Down := FDiagram.ShowClassesNotInInterface;
end;
end;
begin
if FDiagram.IsFileDiagram then //is a diagram of files?
begin
SetClass(False); //first hide buttons specific to class diagrams
SetFile(True); //then show and update buttons for file diagrams
end
else
begin
SetFile(False); //first hide buttons specific to file diagrams
SetClass(True); //then show and update buttons for class diagrams
end;
ComboBoxFont.Text := FDiagram.Font.Name; //show current font and size
{$IFNDEF LINUX}
UpDownFontSize.Position := FDiagram.Font.Size;
{$ENDIF}
//simple class layout only possible in diagrams of classes
// ToolButtonAutoSimpleClassLayOut.Enabled := not FDiagram.IsFileDiagram;
ToolButtonAutoSimpleClassLayOutOptimized.Enabled := not
FDiagram.IsFileDiagram;
if Visible then //window already created?
SetFocus; //focus this window again, in case one of the tool bars is undocked
end;
{Saves each box. This procedure is of type
~[link TForEachGetBoxPositionsRecallProc].
~param TheClass the class of the box, if it is not a file diagram
~param TheFile the file of the box, or the file of the class
~param Position the position of the box
~param Size the size of the box }
procedure TFormDiagram.SaveEachBox(TheClass: TRecordType; TheFile: TPascalFile;
Position, Size: TPoint);
//unique path of class or file depicted by the box
var Path :String;
begin
if assigned(TheClass) then //box depicts a class?
//append name of the class
Path := TheClass.InFile.InternalFileName + '.' + TheClass.Name
else
Path := TheFile.InternalFileName; //use name of the file
//save the path and position of the box
FDiagramSet.WriteString(FSaveSectionName, Path,
Format('%d,%d', [Position.x, Position.y]));
end;
{Saves the current diagram.
~result if the layout of the diagram has been saved }
function TFormDiagram.SaveCurrentLayout: Boolean;
var Name :String; //name of the diagram layout
Sections :TStringList; //internal names of all diagram layouts
Section :String; //internal name of this diagram layout
Scope :TScope; //counter through all possible scopes
Members :TMemberKind; //counter through all kinds of members
//counter through all kinds of record-like type
Classes :TRecordKind;
begin
Result := True; //assume we can save
if FCurrentDiagramIndex = -1 then //diagram layout hasn't been saved so far?
begin
Name := 'New Layout'; //set default name
Result := InputQuery('Name of the Layout', //ask for a name
'Please enter a name for the new layout:', Name);
end
else
Name := ''; //just for the compiler
if Result then //still should be saved?
begin
FTotalChanged := True; //set of diagrams has been changed
Sections := TStringList.Create; //create list for all diagram layouts
try
FDiagramSet.ReadSections(Sections); //read list of all diagram layouts
if FCurrentDiagramIndex = -1 then //diagram hasn't been saved yet?
begin
repeat //generate random internal name
Section := Format(SectionNameFormat, [Random(High(Integer))]);
until Sections.IndexOf(Section) = -1; //until an unused one found
FCurrentDiagramIndex := Sections.Count; //set index of the new section
end
else
begin
Assert((FCurrentDiagramIndex >= 0) and
(FCurrentDiagramIndex < Sections.Count));
Section := Sections[FCurrentDiagramIndex]; //get its internal name
Name := FDiagramSet.ReadString(Section, '.Name', ''); //save its name
FDiagramSet.EraseSection(Section); //delete the diagram layout
FCurrentDiagramIndex := Sections.Count - 1; //use new index
end;
finally
Sections.Free; //free list for all diagram layouts
end;
//write all values of the diagram layout
FDiagramSet.WriteString(Section, '.Name', Name);
FDiagramSet.WriteBool(Section, '.IsFileDiagram', FDiagram.IsFileDiagram);
FDiagramSet.WriteInteger(Section, '.Margin', FDiagram.Margin);
FDiagramSet.WriteString(Section, '.Font.Name', FDiagram.Font.Name);
FDiagramSet.WriteInteger(Section, '.Font.Size', FDiagram.Font.Size);
FDiagramSet.WriteB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -