ADD: ExtensionAPI - TranslateString function

This commit is contained in:
Alexander Koblov 2023-02-25 16:52:24 +03:00
commit 18536d96a9
6 changed files with 143 additions and 58 deletions

View file

@ -101,21 +101,23 @@ typedef int (DCPCALL *tMessageBoxProc)(char* Text, char* Caption, long Flags);
typedef BOOL (DCPCALL *tDialogBoxLFMProc)(intptr_t LFMData, unsigned long DataSize, tDlgProc DlgProc);
typedef BOOL (DCPCALL *tDialogBoxLRSProc)(intptr_t LRSData, unsigned long DataSize, tDlgProc DlgProc);
typedef BOOL (DCPCALL *tDialogBoxLFMFileProc)(char* LFMFileName, tDlgProc DlgProc);
typedef int (DCPCALL *tTranslateStringProc)(void *Translation, const char *Identifier, const char *Original, char *Output, int OutLen);
#pragma pack(push)
#pragma pack(1)
typedef struct {
uint32_t StructSize;
char PluginDir[EXT_MAX_PATH];
char PluginConfDir[EXT_MAX_PATH];
tInputBoxProc InputBox;
tMessageBoxProc MessageBox;
tDialogBoxLFMProc DialogBoxLFM;
tDialogBoxLRSProc DialogBoxLRS;
tDialogBoxLFMFileProc DialogBoxLFMFile;
tDlgProc SendDlgMsg;
unsigned char Reserved[4096 * sizeof(void *)];
uint32_t StructSize;
char PluginDir[EXT_MAX_PATH];
char PluginConfDir[EXT_MAX_PATH];
tInputBoxProc InputBox;
tMessageBoxProc MessageBox;
tDialogBoxLFMProc DialogBoxLFM;
tDialogBoxLRSProc DialogBoxLRS;
tDialogBoxLFMFileProc DialogBoxLFMFile;
tDlgProc SendDlgMsg;
void *Translation;
tTranslateStringProc TranslateString;
unsigned char Reserved[4094 * sizeof(void *)];
} tExtensionStartupInfo;
#pragma pack(pop)

View file

@ -108,6 +108,7 @@ type
TDialogBoxLFMProc = function(LFMData: Pointer; DataSize: LongWord; DlgProc: TDlgProc): LongBool; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
TDialogBoxLRSProc = function(LRSData: Pointer; DataSize: LongWord; DlgProc: TDlgProc): LongBool; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
TDialogBoxLFMFileProc = function(lfmFileName: PAnsiChar; DlgProc: TDlgProc): LongBool; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
TTranslateStringProc = function(Translation: Pointer; Identifier, Original: PAnsiChar; Output: PAnsiChar; OutLen: Integer): Integer {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
type
PExtensionStartupInfo = ^TExtensionStartupInfo;
@ -125,8 +126,10 @@ type
DialogBoxLRS: TDialogBoxLRSProc;
DialogBoxLFMFile: TDialogBoxLFMFileProc;
SendDlgMsg: TDlgProc;
Translation: Pointer;
TranslateString: TTranslateStringProc;
// Reserved for future API extension
Reserved: packed array [0..Pred(4096 * SizeOf(Pointer))] of Byte;
Reserved: packed array [0..Pred(4094 * SizeOf(Pointer))] of Byte;
end;
type

106
src/uextension.pas Normal file
View file

@ -0,0 +1,106 @@
{
Double Commander
-------------------------------------------------------------------------
Extension API implementation
Copyright (C) 2008-2023 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
}
unit uExtension;
{$mode objfpc}{$H+}
{$include calling.inc}
interface
uses
Classes, SysUtils, Extension, Translations;
type
{ TDcxModule }
TDcxModule = class
protected
FPOFile: TPOFile;
FModulePath: String;
FModuleHandle: TLibHandle;
public
destructor Destroy; override;
procedure InitializeExtension(StartupInfo: PExtensionStartupInfo);
end;
implementation
uses
Math, LazFileUtils, DCOSUtils, fDialogBox, uGlobs, uGlobsPaths;
function Translate(Translation: Pointer; Identifier, Original: PAnsiChar; Output: PAnsiChar; OutLen: Integer): Integer; dcpcall;
var
AText: String;
POFile: TPOFile absolute Translation;
begin
if (POFile = nil) then
begin
Result:= 0;
Output^:= #0;
end
else begin
AText:= POFile.Translate(Identifier, Original);
StrPLCopy(Output, AText, OutLen - 1);
Result:= Min(Length(AText), OutLen - 1);
end;
end;
{ TDcxModule }
destructor TDcxModule.Destroy;
begin
inherited Destroy;
FPOFile.Free;
end;
procedure TDcxModule.InitializeExtension(StartupInfo: PExtensionStartupInfo);
var
Language: String;
AFileName, APath: String;
begin
FillByte(StartupInfo^, SizeOf(TExtensionStartupInfo), 0);
AFileName:= FModulePath;
APath:= ExtractFilePath(AFileName) + 'language' + PathDelim;
Language:= ExtractFileExt(ExtractFileNameOnly(gPOFileName));
AFileName:= APath + ExtractFileNameOnly(AFileName) + Language + '.po';
if mbFileExists(AFileName) then FPOFile:= TPOFile.Create(AFileName);
with StartupInfo^ do
begin
StructSize:= SizeOf(TExtensionStartupInfo);
PluginDir:= ExtractFilePath(FModulePath);
PluginConfDir:= gpCfgDir;
InputBox:= @fDialogBox.InputBox;
MessageBox:= @fDialogBox.MessageBox;
DialogBoxLFM:= @fDialogBox.DialogBoxLFM;
DialogBoxLRS:= @fDialogBox.DialogBoxLRS;
DialogBoxLFMFile:= @fDialogBox.DialogBoxLFMFile;
SendDlgMsg:= @fDialogBox.SendDlgMsg;
Translation:= FPOFile;
TranslateString:= @Translate;
end;
end;
end.

View file

@ -29,7 +29,7 @@ unit uWCXmodule;
interface
uses
LCLType, Classes, Dialogs, LazUTF8Classes, dynlibs, SysUtils,
LCLType, Classes, Dialogs, LazUTF8Classes, dynlibs, SysUtils, uExtension,
uWCXprototypes, WcxPlugin, Extension, DCBasicTypes, DCXmlConfig, uClassesEx;
Type
@ -75,10 +75,9 @@ Type
{ TWcxModule }
TWcxModule = class
TWcxModule = class(TDcxModule)
private
FModuleName: String;
FModuleHandle: TLibHandle; // Handle to .DLL or .so
FBackgroundFlags: Integer;
public
@ -254,6 +253,7 @@ begin
//------------------------------------------------------
UnloadModule;
end;
inherited Destroy;
end;
function TWcxModule.OpenArchiveHandle(FileName: String; anOpenMode: Longint; out OpenResult: Longint): TArcHandle;
@ -396,11 +396,12 @@ end;
function TWcxModule.LoadModule(const sName:String):Boolean;
var
PackDefaultParamStruct : TPackDefaultParamStruct;
StartupInfo: TExtensionStartupInfo;
PackDefaultParamStruct : TPackDefaultParamStruct;
begin
FModuleName := ExtractFileName(sName);
FModuleHandle := mbLoadLibrary(mbExpandFileName(sName));
FModulePath := mbExpandFileName(sName);
FModuleHandle := mbLoadLibrary(FModulePath);
if FModuleHandle = 0 then Exit(False);
DCDebug('WCX module loaded ' + sName + ' at ' + hexStr(Pointer(FModuleHandle)));
@ -479,24 +480,11 @@ begin
// Extension API
if Assigned(ExtensionInitialize) then
begin
FillByte(StartupInfo, SizeOf(TExtensionStartupInfo), 0);
begin
InitializeExtension(@StartupInfo);
with StartupInfo do
begin
StructSize:= SizeOf(TExtensionStartupInfo);
PluginDir:= ExtractFilePath(mbExpandFileName(sName));
PluginConfDir:= gpCfgDir;
InputBox:= @fDialogBox.InputBox;
MessageBox:= @fDialogBox.MessageBox;
DialogBoxLFM:= @fDialogBox.DialogBoxLFM;
DialogBoxLRS:= @fDialogBox.DialogBoxLRS;
DialogBoxLFMFile:= @fDialogBox.DialogBoxLFMFile;
SendDlgMsg:= @fDialogBox.SendDlgMsg;
end;
ExtensionInitialize(@StartupInfo);
end;
ExtensionInitialize(@StartupInfo);
end;
end;
procedure TWcxModule.UnloadModule;

View file

@ -36,7 +36,8 @@ uses
Classes, SysUtils, dynlibs,
//DC
uLng, uWdxPrototypes, WdxPlugin, uDetectStr, lua, uFile, DCXmlConfig;
uLng, uWdxPrototypes, WdxPlugin, uDetectStr, lua, uFile, DCXmlConfig,
uExtension;
const
WDX_MAX_LEN = 2048;
@ -59,7 +60,7 @@ type
{ TWDXModule }
TWDXModule = class
TWDXModule = class(TDcxModule)
private
FFieldsList: TStringList;
FParser: TParserControl;
@ -116,7 +117,6 @@ type
TPluginWDX = class(TWDXModule)
protected
FModuleHandle: TLibHandle; // Handle to .DLL or .so
FForce: Boolean;
FName: String;
protected

View file

@ -62,7 +62,6 @@ type
TWFXModule = class(TPluginWDX)
private
FModuleFileName: String;
FBackgroundFlags: Integer;
public
{ Mandatory }
@ -193,7 +192,7 @@ uses
//DC
uDCUtils, uLng, uGlobsPaths, uOSUtils, uWfxPluginUtil, fDialogBox, DCOSUtils,
DCStrUtils, DCConvertEncoding, uComponentsSignature, uOSForms;
DCStrUtils, DCConvertEncoding, uComponentsSignature, uOSForms, uExtension;
const
WfxIniFileName = 'wfx.ini';
@ -640,11 +639,11 @@ begin
EnterCriticalSection(FMutex);
try
if FModuleHandle <> NilHandle then Exit(True);
AHandle := mbLoadLibrary(mbExpandFileName(sName));
FModulePath:= mbExpandFileName(sName);
AHandle := mbLoadLibrary(FModulePath);
Result := AHandle <> NilHandle;
if not Result then Exit;
FModuleFileName:= sName;
{ Mandatory }
FsInit := TFsInit(GetProcAddress(AHandle,'FsInit'));
FsFindFirst := TFsFindFirst(GetProcAddress(AHandle,'FsFindFirst'));
@ -843,24 +842,11 @@ begin
// Extension API
if Assigned(ExtensionInitialize) then
begin
FillByte(StartupInfo, SizeOf(TExtensionStartupInfo), 0);
begin
InitializeExtension(@StartupInfo);
with StartupInfo do
begin
StructSize:= SizeOf(TExtensionStartupInfo);
PluginDir:= ExtractFilePath(mbExpandFileName(FModuleFileName));
PluginConfDir:= gpCfgDir;
InputBox:= @fDialogBox.InputBox;
MessageBox:= @fDialogBox.MessageBox;
DialogBoxLFM:= @fDialogBox.DialogBoxLFM;
DialogBoxLRS:= @fDialogBox.DialogBoxLRS;
DialogBoxLFMFile:= @fDialogBox.DialogBoxLFMFile;
SendDlgMsg:= @fDialogBox.SendDlgMsg;
end;
ExtensionInitialize(@StartupInfo);
end;
ExtensionInitialize(@StartupInfo);
end;
CallContentSetDefaultParams;
CallContentGetSupportedField;