📄 udocumentationtexts.pas
字号:
C: String;
//description of the text
D: String;
end;
//mapping of the scopes to texts describing the scopes
const ScopeTextMapping: array[TScope] of TDocumentationTexts =
(dtScopeUnknown,
dtScopeInterface, dtScopeImplementation,
dtScopePrivate, dtScopeProtected, dtScopePublic, dtScopePublished,
dtScopeAutomated, dtScopeLocal);
//mapping of the scopes to texts describing the scopes
const PortabilityIssueTextMapping: array[TIdentPortability] of
TDocumentationTexts =
(dtPortabilityDeprecated, dtPortabilityLibrary, dtPortabilityPlatform);
//names/texts of the default parents of record-like types and header
//for the list/inheritance hierarchy
DefParentClassNameHeader: array[TRecordKind] of TDocumentationTexts =
(dtDocumentationClassListHeaderRecord,
dtDocumentationClassListHeaderObject,
dtDocumentationClassListHeaderClass,
dtDocumentationClassListHeaderInterface,
dtDocumentationClassListHeaderDispInterface);
{$INCLUDE UDocumentationLocalization.inc }
{ * * * *** * * *** TGeneratorOptionWrapper *** * * *** * * * }
type
{A "special" editor that can be used to edit all texts through the same
interface as the options of all other generators. }
TDocumentationTextOptionWrapper = class(TOptionWrapper)
protected
//Gets the value of an option.
function GetOption(Index: Cardinal): TOptionValue; override;
//Sets the value of an option.
procedure SetOption(Index: Cardinal; const Value: TOptionValue); override;
public
//Returns the number of available options.
function Count: Cardinal; override;
//Gets a description of an option.
procedure Description(Index: Cardinal;
var Desc: TOptionDescription); override;
//Gets the topic of the options.
function DefaultTopic: String; override;
end;
//type containing values for each text of the generators that can be
//changed/localized
type TAllDocumentationTexts = array[TDocumentationTexts] of String;
//so all the values aren't copied, just keep a pointer on them
PAllDocumentationTexts = ^TAllDocumentationTexts;
//Registers pre-defined localized texts to be used by the documentation.
procedure RegisterLocalizedTexts(Texts: PAllDocumentationTexts;
Names: array of String);
//Adds all names of all registered languages to the list.
procedure AddRegisteredLanguages(List: TStrings);
implementation
uses
{$IFOPT C+}
TypInfo, Windows,
{$ENDIF}
SysUtils,
{$IFDEF VER120}
FileCtrl,
{$ENDIF}
IniFiles,
UFilePaths,
UEnglishTexts, UGermanTexts;
//the names of languages the documentation has been localized for;
//the object contains the index of the texts in ~[link LocalizedTexts],
//there may be several names for one language (i.e. the english and the
//native name)
var LocalizedLanguages: TStringList = nil;
//the list of the list of localized texts, accessed via index in
//~[link LocalizedLanguages]
LocalizedTexts: TList = nil;
{Initialize the lists for the registered languages. }
procedure InitLocalizedLanguages;
begin
if not assigned(LocalizedLanguages) then //not yet initialized?
begin
assert(not assigned(LocalizedTexts));
//create lists for registered localized languages
LocalizedLanguages := TStringList.Create;
LocalizedLanguages.Sorted := True; //names have to be unique
LocalizedLanguages.Duplicates := dupError;
LocalizedTexts := TList.Create;
end
else
assert(assigned(LocalizedTexts));
end;
{Registers pre-defined localized texts to be used by the documentation.
~param Texts pointer on the lists of localized texts to be registered
~param Names the list of names to register the texts with, i.e. the english and
the native name of the language }
procedure RegisterLocalizedTexts(Texts: PAllDocumentationTexts;
Names: array of String);
var NewIndex :Integer; //index of the registered localized texts
i :Integer; //counter through names of language
begin
//initialize the lists for the registered languages
InitLocalizedLanguages;
assert(LocalizedTexts.IndexOf(Texts) = -1);
NewIndex := LocalizedTexts.Add(Texts); //add the localized texts
for i := Low(Names) to High(Names) do //for each name
begin
assert(LocalizedLanguages.IndexOf(Names[i]) = -1);
//register it
LocalizedLanguages.AddObject(Names[i], TObject(NewIndex));
end;
end;
{Adds all names of all registered languages to the list.
~param List the list to add the names to }
procedure AddRegisteredLanguages(List: TStrings);
begin
List.AddStrings(LocalizedLanguages); //add all names
end;
//the number of options besides the texts
const OptionCountWithoutTexts = 2;
{Returns the number of available options.
~result the number of available options }
function TDocumentationTextOptionWrapper.Count: Cardinal;
begin
Result := OptionCountWithoutTexts +
Cardinal(Ord(High(TDocumentationTexts)) -
Ord(Low(TDocumentationTexts)) + 1);
end;
{Gets a description of an option.
~param Index index of the option to get data of
~param Desc out: the description of the option (name, type, default value,
etc.) }
procedure TDocumentationTextOptionWrapper.Description(Index: Cardinal;
var Desc: TOptionDescription);
var Text :TDocumentationTexts; //the text to describe
begin
ClearDescription(Desc); //clear structure
case Index of //depending on index of option
0: begin //set the values describing the option
Desc.Name := 'Language';
Desc.Category := '';
Desc.Description := 'Set the texts to a predefined language (write-only); currently only "English" and "German"/"Deutsch" are supported.';
Desc.Options := [ooChangesOtherOptions, ooNoRead];
Desc.DataType := otString;
Desc.StrMaxLen := 0;
end;
1: begin
Desc.Name := 'LanguageFile';
Desc.Category := '';
Desc.Description := 'The file to load texts from (write-only).';
Desc.Options := [ooChangesOtherOptions, ooNoRead];
Desc.DataType := otString;
Desc.StrMaxLen := 0;
Desc.DefaultValue.StrData := '';
end;
OptionCountWithoutTexts..OptionCountWithoutTexts +
Ord(High(TDocumentationTexts)) - Ord(Low(TDocumentationTexts)):
begin
Text := TDocumentationTexts(Index - OptionCountWithoutTexts +
Cardinal(Ord(Low(Text))));
Desc.Name := DocumentationTexts[Text].N;
Desc.Category := DocumentationTexts[Text].C;
Desc.Description := DocumentationTexts[Text].D;
Desc.HelpOptionIndex := HelpOptionIndexNoHelp;
Desc.DataType := otString;
Desc.DefaultValue.StrData := DocumentationTextsEnglish[Text];
end;
else
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
{Gets the value of an option. Call ~[link Description] to get the type and
the meaning of the option.
~param Index index of the option to get the value of
~result the value of the option }
function TDocumentationTextOptionWrapper.GetOption(Index: Cardinal):
TOptionValue;
begin
case Index of //depending on index of option
0: Result.StrData := ''; //get the value
1: Result.StrData := '';
OptionCountWithoutTexts..OptionCountWithoutTexts +
Ord(High(TDocumentationTexts)) - Ord(Low(TDocumentationTexts)):
Result.StrData := DocumentationTexts[
TDocumentationTexts(Index - OptionCountWithoutTexts +
Cardinal(Ord(Low(TDocumentationTexts))))].T;
else
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
{Sets the value of an option. Call ~[link Description] to get the type and
the meaning of the option.
~param Index index of the option to set the value
~param Value the new value of the option}
procedure TDocumentationTextOptionWrapper.SetOption(Index: Cardinal;
const Value: TOptionValue);
{Sets the texts to the text of a language.
~param Texts all texts that can be localized }
procedure SetLanguage(const Name: String);
var Index :Integer; //index of name of the language
Texts :PAllDocumentationTexts; //the localized texts
dt :TDocumentationTexts; //counter through all texts
begin
Index := LocalizedLanguages.IndexOf(Name);
if Index <> -1 then //language known?
begin //get its texts
Texts := LocalizedTexts[Integer(LocalizedLanguages.Objects[Index])];
for dt := Low(dt) to High(dt) do //assign all the texts
DocumentationTexts[dt].T := Texts[dt];
end;
end;
{Reads the texts from a file.
~param FileName the name of the file to load from }
procedure ReadLanguage(FileName: String);
var Ini :TIniFile; //the ini file to read from the file
begin
//is a valid file?
if FileExists(Value.StrData) and not DirectoryExists(FileName) then
begin
{$IFNDEF LINUX}
if (pos(PathDelimiter, FileName) = 0) and (pos(':', FileName) = 0) then
FileName := '.' + PathDelimiter + FileName;
{$ENDIF}
Ini := TIniFile.Create(FileName); //open the file
try
Self.LoadIniOptions(Ini); //read all language strings
finally
Ini.Free; //close the file
end;
end
else
raise Exception.Create('Invalid file, does not exist or is a directory!');
end;
begin
case Index of //depending on index of option
0: if Value.StrData <> '' then //set the value
SetLanguage(LowerCase(Value.StrData));
1: if Value.StrData <> '' then
ReadLanguage(Value.StrData);
OptionCountWithoutTexts..OptionCountWithoutTexts +
Ord(High(TDocumentationTexts)) - Ord(Low(TDocumentationTexts)):
DocumentationTexts[TDocumentationTexts(Index -
OptionCountWithoutTexts +
Cardinal(Ord(Low(TDocumentationTexts))))].T := Value.StrData;
else
raise EInvalidOption.Create('Invalid index for option supplied!');
end;
end;
{Gets the topic of the options.
~result the topic of the options }
function TDocumentationTextOptionWrapper.DefaultTopic: String;
begin
Result := 'TEditDocumentationTexts'; //for backward-compatibility
end;
{$IFOPT C+}
{Checks the consistency of ~[link TDocumentationTexts],
~[link DocumentationTexts] and ~[link DocumentationTextsEnglish] via
assertions. }
procedure CheckTypeConsistency;
var List :TStringList; //list to check for correct names
dt :TDocumentationTexts; //counter through all texts
begin
List := TStringList.Create; //check, if names are unique
try
List.Sorted := True;
for dt := low(dt) to high(dt) do
begin
{$IFNDEF LINUX}
if List.IndexOf(DocumentationTexts[dt].N) <> -1 then
OutputDebugString(PChar(Format('%d: ', [ord(dt)]) +
DocumentationTexts[dt].N));
{$ENDIF}
assert(List.IndexOf(DocumentationTexts[dt].N) = -1);
List.Add(DocumentationTexts[dt].N);
end;
finally
List.Free;
end;
for dt := low(dt) to high(dt) do //check, if texts are consistence
begin
{$IFNDEF LINUX}
if DocumentationTexts[dt].T <> DocumentationTextsEnglish[dt] then
OutputDebugString(PChar(Format('%d: %s: %s <> %s',
[ord(dt),
DocumentationTexts[dt].N,
DocumentationTexts[dt].T,
DocumentationTextsEnglish[dt]])));
{$ENDIF}
Assert(DocumentationTexts[dt].T = DocumentationTextsEnglish[dt]);
end;
for dt := low(dt) to high(dt) do //check, if type is consistence
begin
{$IFNDEF LINUX}
if 'dt' + DocumentationTexts[dt].N <>
GetEnumName(TypeInfo(TDocumentationTexts), ord(dt)) then
OutputDebugString(PChar(Format('%d: ', [ord(dt)]) +
DocumentationTexts[dt].N + ' <> ' +
GetEnumName(TypeInfo(TDocumentationTexts), ord(dt))));
{$ENDIF}
assert('dt' + DocumentationTexts[dt].N =
GetEnumName(TypeInfo(TDocumentationTexts), ord(dt)));
end;
end;
{$ENDIF}
initialization
//create lists for registered localized languages
InitLocalizedLanguages;
{$IFOPT C+}
CheckTypeConsistency;
{$ENDIF}
{
with TEditDocumentationTexts.Create do //create object
try
SetOptionByName('Language', 'english'); //set the english language
finally
Free; //free the object
end;
}
finalization
//free lists for registered localized languages
LocalizedLanguages.Free;
LocalizedTexts.Free;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -