⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udiagramcreator.pas

📁 DelphiDoc is a program for automatic generation of documentation on a Delphi-Project. At the momen
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  //font is unknown? (there are aliases/generic fonts, that can't be checked,
  //                  for instance: "Times" -> "Times New Roman")
  if Screen.Fonts.IndexOf(Value) = -1 then
   AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkFontNotFoundOnSystem),
                    'Warning, font not found on this system: ' + Value);

  FDiagram.Font.Name := Value;    //set the name of the font to use
 end;

 {Returns the boolean value in the string.
 ~param Value   the string expressing a boolean value
 ~param Default the value to use, if string does not represent a valid boolean
                value }
 function CheckBoolean(const Value: String; Default: Boolean): Boolean;
 var      Desc        :TOptionDescription;   //description of a boolean option
          OValue      :TOptionValue;         //boolean value of the option
 begin
  Result := (Value = '');                    //empty string means true
  if not Result then                         //string not empty?
   begin
    ClearDescription(Desc);                    //clear structure
    Desc.DataType := otBoolean;                //set it to a boolean type
    if StringToValue(Value, OValue, Desc) then //try to read boolean value
     Result := OValue.BoolData                   //use tis value
    else
     begin
      Valid := False;                            //error!
      AddSimpleMessage(FDiagramCreatorMessagesID,
                       Ord(dcmkInvalidValueForOption),
                       'Invalid boolean value for option: ' + Value);
      Result := Default;                         //use default value
     end; //else StringToValue(...)
   end; //if not Result
 end;

 {Returns the integer value in the string.
 ~param Value   the string expressing an integer value
 ~param Default the value to use, if string does not represent a valid integer
                value }
 function GetInteger(const Value: String; Default: Integer): Integer;
 var      Code      :Integer;                  //index of error in the string
 begin
  val(Value, Result, Code);                    //try to read the integer value
  if Code <> 0 then                            //not a valid value?
   begin
    Valid := False;                              //error!
    AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkInvalidValueForOption),
                     'Invalid integer value for option: ' + Value);
    Result := Default;                           //use default value
   end;
 end;


 {Sets the kinds of member to be shown in record-like types.
 ~param Str the string defining the kinds of members }
 procedure ReadMemberKinds(const Str: String);
 var       Desc           :TOptionDescription; //an option describing a set
           Value          :TOptionValue;       //value of the set
           Kinds          :TMemberKinds;       //the set of kinds of members
 begin
  ClearDescription(Desc);                      //clear structure
  Desc.DataType := otSet;                      //it is a set of
  Desc.SetNames := OptionItemsFilterMembersByKind; //kinds of members

  if StringToValue(Str, Value, Desc) then      //try to read the kinds
   begin
    OptionToSet(Value.SetData, Kinds, SizeOf(Kinds)); //extract the set
    FDiagram.ShowMembers := Kinds;                      //and use it
   end
  else
   begin                                         //error
    AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkInvalidValueForOption),
                     'Invalid kinds of members to show: ' + Str);
    Valid := False;
   end;
 end;

 {Sets the algorithm to automatically layout the diagram.
 ~param Str the string defining the layout }
 procedure ReadLayout(const Str: String);
 begin
  if Str = 'simple' then         //simple layout for record-like types?
   FLayOut := dloSimple
  else                           //simple layout with post-optimizing?
   if (Str = 'simplepost') or (Str = 'post') or (Str = 'postprocess') or
      (Str = 'simplepostprocess') or (Str = 'optimize') then
    FLayOut := dloSimplePostProcess
   else
    if (Str = 'sugiyama') or (Str = 'default') then //algorithm of Sugiyama?
     FLayOut := dloSugiyama
    else
     AddSimpleMessage(FDiagramCreatorMessagesID,
                      Ord(dcmkInvalidValueForOption),
                      'Invalid layout for diagram: ' + Str);
 end;

 {Sets the scopes of members to be shown in record-like types.
 ~param Str the string defining the scopes }
 procedure ReadScopes(const Str: String);
 var       Desc      :TOptionDescription;   //an option describing a set
           Value     :TOptionValue;         //value of the set
           Scopes    :set of TMemberScopes; //the set of scopes
 begin
  ClearDescription(Desc);                   //clear structure
  Desc.DataType := otSet;                   //it is a set of
  Desc.SetNames := OptionItemsFilterMembersByScope; //scopes of members

  if StringToValue(Str, Value, Desc) then      //try to read the kinds
   begin
    //extract the set of scopes
    OptionToSet(Value.SetData, Scopes, SizeOf(Scopes), Ord(Low(TMemberScope)));
    FDiagram.ShowScopes := Scopes;               //and use it
   end
  else
   begin                                         //error
    AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkInvalidValueForOption),
                     'Invalid scopes of members to show: ' + Str);
    Valid := False;
   end;
 end;


var      Name            :String;        //the name of the option
         OptionIndex     :Integer;       //index of the option
         i               :Integer;       //index of end of name of option
         ShowRecordKinds :TRecordKinds;  //kinds of record-like types to show
begin
 Name := Option;
 i := pos('=', Name);                    //get separator between name and value
 if i = 0 then                           //no value?
  Option := ''                             //no value
 else
  begin
   Delete(Name, i, High(Length(Name)));    //extract the name
   Delete(Option, 1, i);                   //extract the value
  end;

 if IsWordIn(Name, DiagramOptionNames, OptionIndex) then //is a valid option?
  begin
   if TDiagramOption(OptionIndex) <> doFont then //not the name of a font?
    Option := LowerCase(Option);                  //values are case-insensitive
   Valid := True;
   case TDiagramOption(OptionIndex) of       //handle the option
     doAssociations:   FDiagram.ShowAssociations := CheckBoolean(Option,
                                                    FDiagram.ShowAssociations);
     doClass,
     doFile:           FDiagram.NewDiagram(TDiagramOption(OptionIndex) =
                                           doFile);
     doFont:           SetFont(Option);
     doImplementation: FDiagram.ShowUsingImplementation :=
                        CheckBoolean(Option, FDiagram.ShowUsingImplementation);
     doMemberKinds:    ReadMemberKinds(Option);
     doLayout:         ReadLayout(Option);
     doMargin:         FDiagram.Margin := GetInteger(Option, FDiagram.Margin);
     doParameter:      FDiagram.ShowMethodParameters := CheckBoolean(Option,
                                                FDiagram.ShowMethodParameters);
     doResult:         FDiagram.ShowReturnType := CheckBoolean(Option,
                                                      FDiagram.ShowReturnType);
     doScopes:         ReadScopes(Option);
     doShowFile:       FDiagram.ShowFileNameInClass := CheckBoolean(Option,
                                                 FDiagram.ShowFileNameInClass);
     doShowPrivate:    FDiagram.ShowClassesNotInInterface :=
                              CheckBoolean(Option,
                                           FDiagram.ShowClassesNotInInterface);
     doSize:           FDiagram.Font.Size := GetInteger(Option,
                                                        FDiagram.Font.Size);
     doTypes:          if GetRecordLikeTypeSet(Option, ShowRecordKinds) then
                        FDiagram.ShowClasses := ShowRecordKinds
                       else
                        begin
                         Valid := False;
                        end;
   else
    assert(False);
   end;
{
   if Valid and not             //was a valid option that changed the diagram?
      (TDiagramOption(OptionIndex) in [doClass, doFile, doLayout]) then
    FDiagram.ApplyOptions         //apply the new option
}
  end
 else
  AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkUnknownOption),
                   'Unknown option: ' + Name);
end;

















{Handles the first part of classes to add or remove from the diagram.
~param ClassName the name fo the class or generic command
~param Parameter parameter to the class or command
~param List      the list to add the class(es) to
~result whether the class(es) has/ve been successfully added }
function TDiagramCreator.AddSubClassStart(const ClassName, Parameter: String;
                                          List: TList): Boolean;

 {Adds all classes in the file. }
 procedure AddAllClassesInTheFile;
 var       TheFile       :TPascalFile;     //file of the classes to add
           i             :Integer;         //counter through the identifiers
           Ident         :TIdentifier;     //each identifier in the file
 begin
  if (Parameter = '') or                   //check the file
     (Parameter[1] <> '(') or (Parameter[Length(Parameter)] <> ')') then
   AddSimpleMessage(FDiagramCreatorMessagesID,
                    Ord(dcmkNoFileSpecifiedForClass),
                    Format('No file given for "%s(name of file)"!',
                           [ClassName]))
  else
   begin                                   //search the file
    TheFile := FFiles.GetFileByName(copy(Parameter, 2,
                                         Length(Parameter) - 2));
    if not assigned(TheFile) then
     AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkFileNotFound),
                      Format('File not found: "%s"!',
                             [copy(Parameter, 2, Length(Parameter) - 2)]))
    else
     begin
      for i := 0 to TheFile.Idents.Count - 1 do  //for each identifier in it
       begin
        Ident := TheFile.Idents[i];                //get it
         //is a valid class?
        if (Ident is TRecordType) and not DoNotDocumentIdentifier(Ident) then
         Add(List, Ident);                           //add it to the list
       end;
       Result := True;                           //command was correct
     end; //else not assigned(TheFile)
   end; //else Parameter invalid
 end;


 {Adds all record-like types of the kinds. }
 procedure AddAllClassesOfKinds;
 var       FilterSet      :TRecordKinds;    //kinds of record-like types to add
           i              :Integer;         //counter through the files
           TheFile        :TPascalFile;     //each file
           j              :Integer;         //counter through the identifiers
           Ident          :TIdentifier;     //all identifiers
 begin
  if (Parameter = '') or                    //parameter given?
     (Parameter[1] <> '(') or (Parameter[Length(Parameter)] <> ')') then
   AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkParameters),
                    Format('"%s()" needs a parameter!', [ClassName]))
  else
   begin
    //extract kinds of record-like types to add
    Result := GetRecordLikeTypeSet(copy(Parameter, 2, Length(Parameter) - 2),
                                   FilterSet);
    if Result and (FilterSet <> []) then      //set of kinds valid?
     for i := 0 to FFiles.Count - 1 do          //for each file
      begin
       TheFile := FFiles[i];
       for j := 0 to TheFile.Idents.Count - 1 do  //for each identifier
        begin
         Ident := TheFile.Idents[j];
         if (Ident is TRecordType) and              //is a valid class?
            (TRecordType(Ident).Kind in FilterSet) and
            not DoNotDocumentIdentifier(Ident) then
          Add(List, Ident);                           //add it to the list
        end; //for j := 0 to TheFile.Idents.Count - 1
      end; //for i := 0 to FFiles.Count - 1
   end; //else Parameter invalid
 end;


var      Ident          :TIdentifier;     //the specified class to add
         TheFile        :TPascalFile;     //the file of the class to add
         i              :Integer;         //counter through the files
begin
 Result := False;                         //not proved correct yet
 if LowerCase(ClassName) = 'file' then    //classes in file should be added?
  AddAllClassesInTheFile                    //add all classes in the file
 else
  //all record-like types of the kinds should be added?
  if LowerCase(ClassName) = 'type' then
   AddAllClassesOfKinds                     //add all types of the kinds
  else
   begin //name of a record-like type given
    Ident := nil;                           //class not found so far

    if Parameter <> '' then                 //file specified?
     begin                                    //file valid?
      if (Parameter[1] <> '(') or (Parameter[Length(Parameter)] <> ')') then
       AddSimpleMessage(FDiagramCreatorMessagesID,
                        Ord(dcmkInvalidFileSpecified),
                        Format('No valid file given for %s(File)!',
                               [ClassName]))
      else
       begin
        TheFile := FFiles.GetFileByName(copy(Parameter, 2,
                                             Length(Parameter) - 2));
        if not assigned(TheFile) then         //file not found?
         AddSimpleMessage(FDiagramCreatorMessagesID, Ord(dcmkFileNotFound),
                          Format('File not found: "%s"!',
                                 [copy(Parameter, 2, Length(Parameter) - 2)]))
        else
         begin                                //search class in the file
          Ident := TheFile.Idents.GetIdentByName(ClassName);
          //is not a valid class?
          if not (Ident is TRecordType) or DoNotDocumentIdentifier(Ident) then
           AddSimpleMessage(FDiagramCreatorMessagesID,
                            Ord(dcmkClassNotFoundInFile),
                            Format('No class "%s" in file "%s" found!',
                                   [ClassName,
                                    copy(Parameter, 2,
                                         Length(Parameter) - 2)]))
          else
           begin
            List.Add(Ident);                    //add it to the list
            Result := True;                     //class was valid
           end; //else Ident not found or invalid
         end; //else not assigned(TheFile)
       end; //else Parameter invalid
     end //if Parameter <> ''
    else
     begin
      if assigned(FStartFile) then      //file to start searched defined?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -