📄 gnugettext.pas
字号:
end else begin
// This part should only happen on Windows 95.
langid := GetThreadLocale;
case langid of
IDBelgianDutch: langcode := 'nl_BE';
IDBelgianFrench: langcode := 'fr_BE';
IDBrazilianPortuguese: langcode := 'pt_BR';
IDDanish: langcode := 'da_DK';
IDDutch: langcode := 'nl_NL';
IDEnglishUK: langcode := 'en_GB';
IDEnglishUS: langcode := 'en_US';
IDFinnish: langcode := 'fi_FI';
IDFrench: langcode := 'fr_FR';
IDFrenchCanadian: langcode := 'fr_CA';
IDGerman: langcode := 'de_DE';
IDGermanLuxembourg: langcode := 'de_LU';
IDGreek: langcode := 'el_GR';
IDIcelandic: langcode := 'is_IS';
IDItalian: langcode := 'it_IT';
IDKorean: langcode := 'ko_KO';
IDNorwegianBokmol: langcode := 'nb_NO';
IDNorwegianNynorsk: langcode := 'nn_NO';
IDPolish: langcode := 'pl_PL';
IDPortuguese: langcode := 'pt_PT';
IDRussian: langcode := 'ru_RU';
IDSpanish, IDSpanishModernSort: langcode := 'es_ES';
IDSwedish: langcode := 'sv_SE';
IDSwedishFinland: langcode := 'sv_FI';
else
langcode := 'C';
end;
end;
Result := langcode;
end;
{$endif}
function LoadResStringA(ResStringRec: PResStringRec): string;
begin
Result:=DefaultInstance.LoadResString(ResStringRec);
end;
function GetTranslatorNameAndEmail:widestring;
begin
Result:=DefaultInstance.GetTranslatorNameAndEmail;
end;
procedure UseLanguage(LanguageCode: string);
begin
DefaultInstance.UseLanguage(LanguageCode);
end;
type
PStrData = ^TStrData;
TStrData = record
Ident: Integer;
Str: string;
end;
function SysUtilsEnumStringModules(Instance: Longint; Data: Pointer): Boolean;
{$IFDEF MSWINDOWS}
var
Buffer: array [0..1023] of char;
begin
with PStrData(Data)^ do begin
SetString(Str, Buffer,
LoadString(Instance, Ident, Buffer, sizeof(Buffer)));
Result := Str = '';
end;
end;
{$ENDIF}
{$IFDEF LINUX}
var
rs:TResStringRec;
Module:HModule;
begin
Module:=Instance;
rs.Module:=@Module;
with PStrData(Data)^ do begin
rs.Identifier:=Ident;
Str:=System.LoadResString(@rs);
Result:=Str='';
end;
end;
{$ENDIF}
function SysUtilsFindStringResource(Ident: Integer): string;
var
StrData: TStrData;
begin
StrData.Ident := Ident;
StrData.Str := '';
EnumResourceModules(SysUtilsEnumStringModules, @StrData);
Result := StrData.Str;
end;
function SysUtilsLoadStr(Ident: Integer): string;
begin
{$ifdef DXGETTEXTDEBUG}
DefaultInstance.DebugWriteln ('Sysutils.LoadRes('+IntToStr(ident)+') called');
{$endif}
Result := ResourceStringGettext(SysUtilsFindStringResource(Ident));
end;
function SysUtilsFmtLoadStr(Ident: Integer; const Args: array of const): string;
begin
{$ifdef DXGETTEXTDEBUG}
DefaultInstance.DebugWriteln ('Sysutils.FmtLoadRes('+IntToStr(ident)+',Args) called');
{$endif}
FmtStr(Result, SysUtilsFindStringResource(Ident), Args);
Result:=ResourceStringGettext(Result);
end;
function LoadResString(ResStringRec: PResStringRec): widestring;
begin
Result:=DefaultInstance.LoadResString(ResStringRec);
end;
function LoadResStringW(ResStringRec: PResStringRec): widestring;
begin
Result:=DefaultInstance.LoadResString(ResStringRec);
end;
function GetCurrentLanguage:string;
begin
Result:=DefaultInstance.GetCurrentLanguage;
end;
{ TDomain }
procedure TDomain.CloseMoFile;
begin
if mofile<>nil then begin
FileLocator.ReleaseMoFile(mofile);
mofile:=nil;
end;
OpenHasFailedBefore:=False;
end;
destructor TDomain.Destroy;
begin
CloseMoFile;
inherited;
end;
{$ifdef mswindows}
function GetLastWinError:string;
var
errcode:Cardinal;
begin
SetLength (Result,2000);
errcode:=GetLastError();
Windows.FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,nil,errcode,0,PChar(Result),2000,nil);
Result:=StrPas(PChar(Result));
end;
{$endif}
procedure TDomain.OpenMoFile;
var
filename: string;
begin
// Check if it is already open
if mofile<>nil then
exit;
// Check if it has been attempted to open the file before
if OpenHasFailedBefore then
exit;
if SpecificFilename<>'' then begin
filename:=SpecificFilename;
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('Domain '+domain+' is bound to specific file '+filename);
{$endif}
end else begin
filename := Directory + curlang + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo';
if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then begin
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('Domain '+domain+': File does not exist, neither embedded or in file system: '+filename);
{$endif}
filename := Directory + copy(curlang, 1, 2) + PathDelim + 'LC_MESSAGES' + PathDelim + domain + '.mo';
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('Domain '+domain+' will attempt to use this file: '+filename);
{$endif}
end else begin
{$ifdef DXGETTEXTDEBUG}
if FileLocator.FileExists(filename) then
DebugLogger ('Domain '+domain+' will attempt to use this embedded file: '+filename)
else
DebugLogger ('Domain '+domain+' will attempt to use this file that was found on the file system: '+filename);
{$endif}
end;
end;
if (not FileLocator.FileExists(filename)) and (not fileexists(filename)) then begin
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('Domain '+domain+' failed to locate the file: '+filename);
{$endif}
OpenHasFailedBefore:=True;
exit;
end;
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('Domain '+domain+' now accesses the file.');
{$endif}
mofile:=FileLocator.GetMoFile(filename, DebugLogger);
{$ifdef DXGETTEXTDEBUG}
if mofile.isSwappedArchitecture then
DebugLogger ('.mo file is swapped (comes from another CPU architecture)');
{$endif}
// Check, that the contents of the file is utf-8
if pos('CHARSET=UTF-8',uppercase(GetTranslationProperty('Content-Type')))=0 then begin
CloseMoFile;
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.');
{$endif}
{$ifdef MSWINDOWS}
MessageBox(0,PChar('The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.'),'Localization problem',MB_OK);
{$else}
writeln (stderr,'The translation for the language code '+curlang+' (in '+filename+') does not have charset=utf-8 in its Content-Type. Translations are turned off.');
{$endif}
Enabled:=False;
end;
end;
function TDomain.GetTranslationProperty(
Propertyname: string): WideString;
var
sl:TStringList;
i:integer;
s:string;
begin
Propertyname:=uppercase(Propertyname)+': ';
sl:=TStringList.Create;
try
sl.Text:=gettext(''); // Everything is UTF-8
for i:=0 to sl.Count-1 do begin
s:=sl.Strings[i];
if uppercase(copy(s,1,length(Propertyname)))=Propertyname then begin
Result:=utf8decode(trim(copy(s,length(PropertyName)+1,maxint)));
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('GetTranslationProperty('+PropertyName+') returns '''+Result+'''.');
{$endif}
exit;
end;
end;
finally
FreeAndNil (sl);
end;
Result:='';
{$ifdef DXGETTEXTDEBUG}
DebugLogger ('GetTranslationProperty('+PropertyName+') did not find any value. An empty string is returned.');
{$endif}
end;
procedure TDomain.setDirectory(const dir: string);
begin
vDirectory := IncludeTrailingPathDelimiter(dir);
SpecificFilename:='';
CloseMoFile;
end;
procedure AddDomainForResourceString (const domain:string);
begin
{$ifdef DXGETTEXTDEBUG}
DefaultInstance.DebugWriteln ('Extra domain for resourcestring: '+domain);
{$endif}
ResourceStringDomainListCS.BeginWrite;
try
if ResourceStringDomainList.IndexOf(domain)=-1 then
ResourceStringDomainList.Add (domain);
finally
ResourceStringDomainListCS.EndWrite;
end;
end;
procedure RemoveDomainForResourceString (const domain:string);
var
i:integer;
begin
{$ifdef DXGETTEXTDEBUG}
DefaultInstance.DebugWriteln ('Remove domain for resourcestring: '+domain);
{$endif}
ResourceStringDomainListCS.BeginWrite;
try
i:=ResourceStringDomainList.IndexOf(domain);
if i<>-1 then
ResourceStringDomainList.Delete (i);
finally
ResourceStringDomainListCS.EndWrite;
end;
end;
procedure TDomain.SetLanguageCode(const langcode: string);
begin
CloseMoFile;
curlang:=langcode;
end;
function GetPluralForm2EN(Number: Integer): Integer;
begin
Number:=abs(Number);
if Number=1 then Result:=0 else Result:=1;
end;
function GetPluralForm1(Number: Integer): Integer;
begin
Result:=0;
end;
function GetPluralForm2FR(Number: Integer): Integer;
begin
Number:=abs(Number);
if (Number=1) or (Number=0) then Result:=0 else Result:=1;
end;
function GetPluralForm3LV(Number: Integer): Integer;
begin
Number:=abs(Number);
if (Number mod 10=1) and (Number mod 100<>11) then
Result:=0
else
if Number<>0 then Result:=1
else Result:=2;
end;
function GetPluralForm3GA(Number: Integer): Integer;
begin
Number:=abs(Number);
if Number=1 then Result:=0
else if Number=2 then Result:=1
else Result:=2;
end;
function GetPluralForm3LT(Number: Integer): Integer;
var
n1,n2:byte;
begin
Number:=abs(Number);
n1:=Number mod 10;
n2:=Number mod 100;
if (n1=1) and (n2<>11) then
Result:=0
else
if (n1>=2) and ((n2<10) or (n2>=20)) then Result:=1
else Result:=2;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -