mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Unicode support for WCX plugins
This commit is contained in:
parent
dcfbd364d4
commit
736e257fe4
5 changed files with 163 additions and 65 deletions
|
|
@ -60,28 +60,43 @@ var
|
|||
// (There may be other running concurrently, but only one may report progress.)
|
||||
WcxCopyInOperation: TWcxArchiveCopyInOperation = nil;
|
||||
|
||||
function ChangeVolProc(ArcName : PAnsiChar; Mode:Longint):Longint; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
function ChangeVolProc(var ArcName : UTF8String; Mode: LongInt): LongInt;
|
||||
begin
|
||||
Result:= 1;
|
||||
sArcName:= SysToUTF8(ArcName);
|
||||
case Mode of
|
||||
PK_VOL_ASK:
|
||||
begin
|
||||
// Use operation UI for this?
|
||||
if ShowInputQuery('Double Commander', rsMsgSelLocNextVol, sArcName) then
|
||||
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH)
|
||||
else
|
||||
if not ShowInputQuery('Double Commander', rsMsgSelLocNextVol, ArcName) then
|
||||
Result := 0; // Abort operation
|
||||
end;
|
||||
PK_VOL_NOTIFY:
|
||||
if log_arc_op in gLogOptions then
|
||||
LogWrite(rsMsgNextVolUnpack + #32 + sArcName);
|
||||
LogWrite(rsMsgNextVolUnpack + #32 + ArcName);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ProcessDataProc(FileName: PChar; Size: Integer): Integer; stdcall;
|
||||
function ChangeVolProcA(ArcName : PAnsiChar; Mode: LongInt): LongInt; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
begin
|
||||
sArcName:= SysToUTF8(StrPas(ArcName));
|
||||
Result:= ChangeVolProc(sArcName, Mode);
|
||||
if Result <> 0 then
|
||||
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH);
|
||||
end;
|
||||
|
||||
function ChangeVolProcW(ArcName : PWideChar; Mode: LongInt): LongInt; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
begin
|
||||
sArcName:= UTF8Encode(WideString(ArcName));
|
||||
Result:= ChangeVolProc(sArcName, Mode);
|
||||
if Result <> 0 then
|
||||
StrPLCopyW(ArcName, UTF8Decode(sArcName), MAX_PATH);
|
||||
end;
|
||||
|
||||
function ProcessDataProc(FileName: UTF8String; Size: LongInt): LongInt;
|
||||
begin
|
||||
//DebugLn('Working ' + FileName + ' Size = ' + IntToStr(Size));
|
||||
|
||||
|
|
@ -126,6 +141,16 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ProcessDataProcA(FileName: PAnsiChar; Size: LongInt): LongInt; stdcall;
|
||||
begin
|
||||
Result:= ProcessDataProc(SysToUTF8(StrPas(FileName)), Size);
|
||||
end;
|
||||
|
||||
function ProcessDataProcW(FileName: PWideChar; Size: LongInt): LongInt; stdcall;
|
||||
begin
|
||||
Result:= ProcessDataProc(UTF8Encode(WideString(FileName)), Size);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
constructor TWcxArchiveCopyInOperation.Create(aSourceFileSource: IFileSource;
|
||||
|
|
@ -167,7 +192,6 @@ end;
|
|||
|
||||
procedure TWcxArchiveCopyInOperation.MainExecute;
|
||||
var
|
||||
pDestPath: PChar;
|
||||
sDestPath: String;
|
||||
WcxModule: TWcxModule;
|
||||
iResult: Longint;
|
||||
|
|
@ -176,21 +200,16 @@ begin
|
|||
|
||||
sDestPath := ExcludeFrontPathDelimiter(TargetPath);
|
||||
sDestPath := ExcludeTrailingPathDelimiter(sDestPath);
|
||||
sDestPath := UTF8ToSys(sDestPath);
|
||||
sDestPath := sDestPath;
|
||||
|
||||
if sDestPath = '' then
|
||||
pDestPath := nil
|
||||
else
|
||||
pDestPath := PAnsiChar(sDestPath); // Make pointer to local variable
|
||||
WcxModule.WcxSetChangeVolProc(wcxInvalidHandle, @ChangeVolProcA, @ChangeVolProcW);
|
||||
WcxModule.WcxSetProcessDataProc(wcxInvalidHandle, @ProcessDataProcA, @ProcessDataProcW);
|
||||
|
||||
WcxModule.SetChangeVolProc(wcxInvalidHandle, @ChangeVolProc);
|
||||
WcxModule.SetProcessDataProc(wcxInvalidHandle, @ProcessDataProc);
|
||||
|
||||
iResult := WcxModule.PackFiles(
|
||||
PAnsiChar(UTF8ToSys(FWcxArchiveFileSource.ArchiveFileName)),
|
||||
pDestPath, // no trailing path delimiter here
|
||||
PAnsiChar(UTF8ToSys(IncludeTrailingPathDelimiter(FFullFilesTree.Path))), // end with path delimiter here
|
||||
PAnsiChar(UTF8ToSys(GetFileList(FFullFilesTree))), // Convert TFiles into PAnsiChar
|
||||
iResult := WcxModule.WcxPackFiles(
|
||||
FWcxArchiveFileSource.ArchiveFileName,
|
||||
sDestPath, // no trailing path delimiter here
|
||||
IncludeTrailingPathDelimiter(FFullFilesTree.Path), // end with path delimiter here
|
||||
GetFileList(FFullFilesTree), // Convert TFiles into UTF8String
|
||||
FWcxArchiveFileSource.PluginFlags);
|
||||
|
||||
// Check for errors.
|
||||
|
|
|
|||
|
|
@ -82,28 +82,43 @@ var
|
|||
// (There may be other running concurrently, but only one may report progress.)
|
||||
WcxCopyOutOperation: TWcxArchiveCopyOutOperation = nil;
|
||||
|
||||
function ChangeVolProc(ArcName : PAnsiChar; Mode:Longint):Longint; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
function ChangeVolProc(var ArcName : UTF8String; Mode: LongInt): LongInt;
|
||||
begin
|
||||
Result:= 1;
|
||||
sArcName:= SysToUTF8(ArcName);
|
||||
case Mode of
|
||||
PK_VOL_ASK:
|
||||
begin
|
||||
// Use operation UI for this?
|
||||
if ShowInputQuery('Double Commander', rsMsgSelLocNextVol, sArcName) then
|
||||
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH)
|
||||
else
|
||||
if not ShowInputQuery('Double Commander', rsMsgSelLocNextVol, ArcName) then
|
||||
Result := 0; // Abort operation
|
||||
end;
|
||||
PK_VOL_NOTIFY:
|
||||
if log_arc_op in gLogOptions then
|
||||
LogWrite(rsMsgNextVolUnpack + #32 + sArcName);
|
||||
LogWrite(rsMsgNextVolUnpack + #32 + ArcName);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ProcessDataProc(FileName: PChar; Size: Integer): Integer; stdcall;
|
||||
function ChangeVolProcA(ArcName : PAnsiChar; Mode: LongInt): LongInt; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
begin
|
||||
sArcName:= SysToUTF8(StrPas(ArcName));
|
||||
Result:= ChangeVolProc(sArcName, Mode);
|
||||
if Result <> 0 then
|
||||
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH);
|
||||
end;
|
||||
|
||||
function ChangeVolProcW(ArcName : PWideChar; Mode: LongInt): LongInt; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
begin
|
||||
sArcName:= UTF8Encode(WideString(ArcName));
|
||||
Result:= ChangeVolProc(sArcName, Mode);
|
||||
if Result <> 0 then
|
||||
StrPLCopyW(ArcName, UTF8Decode(sArcName), MAX_PATH);
|
||||
end;
|
||||
|
||||
function ProcessDataProc(FileName: UTF8String; Size: LongInt): LongInt;
|
||||
begin
|
||||
//DebugLn('Working ' + FileName + ' Size = ' + IntToStr(Size));
|
||||
|
||||
|
|
@ -148,6 +163,16 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ProcessDataProcA(FileName: PAnsiChar; Size: LongInt): LongInt; stdcall;
|
||||
begin
|
||||
Result:= ProcessDataProc(SysToUTF8(StrPas(FileName)), Size);
|
||||
end;
|
||||
|
||||
function ProcessDataProcW(FileName: PWideChar; Size: LongInt): LongInt; stdcall;
|
||||
begin
|
||||
Result:= ProcessDataProc(UTF8Encode(WideString(FileName)), Size);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
constructor TWcxArchiveCopyOutOperation.Create(aSourceFileSource: IFileSource;
|
||||
|
|
@ -221,14 +246,14 @@ begin
|
|||
// Operation allowed to run, but not to report progress.
|
||||
if WcxCopyOutOperation <> Self then
|
||||
begin
|
||||
WcxModule.SetChangeVolProc(ArcHandle, nil);
|
||||
WcxModule.SetProcessDataProc(ArcHandle, nil);
|
||||
WcxModule.WcxSetChangeVolProc(ArcHandle, nil, nil);
|
||||
WcxModule.WcxSetProcessDataProc(ArcHandle, nil, nil);
|
||||
end
|
||||
else
|
||||
{$ENDIF}
|
||||
begin
|
||||
WcxModule.SetChangeVolProc(ArcHandle, @ChangeVolProc);
|
||||
WcxModule.SetProcessDataProc(ArcHandle, @ProcessDataProc);
|
||||
WcxModule.WcxSetChangeVolProc(ArcHandle, @ChangeVolProcA, @ChangeVolProcW);
|
||||
WcxModule.WcxSetProcessDataProc(ArcHandle, @ProcessDataProcA, @ProcessDataProcW);
|
||||
end;
|
||||
|
||||
while (WcxModule.ReadWCXHeader(ArcHandle, Header) = E_SUCCESS) do
|
||||
|
|
@ -256,7 +281,7 @@ begin
|
|||
FCurrentFileSize := Header.UnpSize;
|
||||
end;
|
||||
|
||||
iResult := WcxModule.ProcessFile(ArcHandle, PK_EXTRACT, nil, PAnsiChar(UTF8ToSys(TargetFileName)));
|
||||
iResult := WcxModule.WcxProcessFile(ArcHandle, PK_EXTRACT, EmptyStr, TargetFileName);
|
||||
|
||||
if iResult <> E_SUCCESS then
|
||||
begin
|
||||
|
|
|
|||
|
|
@ -61,28 +61,43 @@ var
|
|||
// (There may be other running concurrently, but only one may report progress.)
|
||||
WcxDeleteOperation: TWcxArchiveDeleteOperation = nil;
|
||||
|
||||
function ChangeVolProc(ArcName : PAnsiChar; Mode:Longint):Longint; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
function ChangeVolProc(var ArcName : UTF8String; Mode: LongInt): LongInt;
|
||||
begin
|
||||
Result:= 1;
|
||||
sArcName:= SysToUTF8(ArcName);
|
||||
case Mode of
|
||||
PK_VOL_ASK:
|
||||
begin
|
||||
// Use operation UI for this?
|
||||
if ShowInputQuery('Double Commander', rsMsgSelLocNextVol, sArcName) then
|
||||
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH)
|
||||
else
|
||||
if not ShowInputQuery('Double Commander', rsMsgSelLocNextVol, ArcName) then
|
||||
Result := 0; // Abort operation
|
||||
end;
|
||||
PK_VOL_NOTIFY:
|
||||
if log_arc_op in gLogOptions then
|
||||
LogWrite(rsMsgNextVolUnpack + #32 + sArcName);
|
||||
LogWrite(rsMsgNextVolUnpack + #32 + ArcName);
|
||||
end;
|
||||
end;
|
||||
|
||||
function ProcessDataProc(FileName: PChar; Size: Integer): Integer; stdcall;
|
||||
function ChangeVolProcA(ArcName : PAnsiChar; Mode: LongInt): LongInt; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
begin
|
||||
sArcName:= SysToUTF8(StrPas(ArcName));
|
||||
Result:= ChangeVolProc(sArcName, Mode);
|
||||
if Result <> 0 then
|
||||
StrPLCopy(ArcName, UTF8ToSys(sArcName), MAX_PATH);
|
||||
end;
|
||||
|
||||
function ChangeVolProcW(ArcName : PWideChar; Mode: LongInt): LongInt; stdcall;
|
||||
var
|
||||
sArcName: UTF8String;
|
||||
begin
|
||||
sArcName:= UTF8Encode(WideString(ArcName));
|
||||
Result:= ChangeVolProc(sArcName, Mode);
|
||||
if Result <> 0 then
|
||||
StrPLCopyW(ArcName, UTF8Decode(sArcName), MAX_PATH);
|
||||
end;
|
||||
|
||||
function ProcessDataProc(FileName: UTF8String; Size: LongInt): LongInt;
|
||||
begin
|
||||
//DebugLn('Working ' + FileName + ' Size = ' + IntToStr(Size));
|
||||
|
||||
|
|
@ -95,7 +110,7 @@ begin
|
|||
|
||||
with WcxDeleteOperation.FStatistics do
|
||||
begin
|
||||
CurrentFile := SysToUTF8(FileName);
|
||||
CurrentFile := FileName;
|
||||
|
||||
if Size >= 0 then
|
||||
begin
|
||||
|
|
@ -128,6 +143,16 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ProcessDataProcA(FileName: PAnsiChar; Size: LongInt): LongInt; stdcall;
|
||||
begin
|
||||
Result:= ProcessDataProc(SysToUTF8(StrPas(FileName)), Size);
|
||||
end;
|
||||
|
||||
function ProcessDataProcW(FileName: PWideChar; Size: LongInt): LongInt; stdcall;
|
||||
begin
|
||||
Result:= ProcessDataProc(UTF8Encode(WideString(FileName)), Size);
|
||||
end;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
constructor TWcxArchiveDeleteOperation.Create(aTargetFileSource: IFileSource;
|
||||
|
|
@ -164,12 +189,11 @@ var
|
|||
begin
|
||||
WcxModule := FWcxArchiveFileSource.WcxModule;
|
||||
|
||||
WcxModule.SetChangeVolProc(wcxInvalidHandle, @ChangeVolProc);
|
||||
WcxModule.SetProcessDataProc(wcxInvalidHandle, @ProcessDataProc);
|
||||
WcxModule.WcxSetChangeVolProc(wcxInvalidHandle, @ChangeVolProcA, @ChangeVolProcW);
|
||||
WcxModule.WcxSetProcessDataProc(wcxInvalidHandle, @ProcessDataProcA, @ProcessDataProcW);
|
||||
|
||||
iResult := WcxModule.DeleteFiles(
|
||||
PAnsiChar(UTF8ToSys(FWcxArchiveFileSource.ArchiveFileName)),
|
||||
PAnsiChar(UTF8ToSys(GetFileList(FilesToDelete))));
|
||||
iResult := WcxModule.WcxDeleteFiles(FWcxArchiveFileSource.ArchiveFileName,
|
||||
GetFileList(FilesToDelete));
|
||||
|
||||
// Check for errors.
|
||||
if iResult <> E_SUCCESS then
|
||||
|
|
|
|||
|
|
@ -387,9 +387,9 @@ begin
|
|||
Exit;
|
||||
end;
|
||||
|
||||
if bCanYouHandleThisFile and Assigned(WcxModule.CanYouHandleThisFile) then
|
||||
if bCanYouHandleThisFile and (Assigned(WcxModule.CanYouHandleThisFile) or Assigned(WcxModule.CanYouHandleThisFileW)) then
|
||||
begin
|
||||
Result := WcxModule.CanYouHandleThisFile(PChar(UTF8ToSys(ArchiveFileName)));
|
||||
Result := WcxModule.WcxCanYouHandleThisFile(ArchiveFileName);
|
||||
if not Result then Exit;
|
||||
end;
|
||||
|
||||
|
|
@ -441,7 +441,7 @@ begin
|
|||
FArcFileList.Add(Header);
|
||||
|
||||
// get next file
|
||||
iResult := WcxModule.ProcessFile(ArcHandle, PK_SKIP, nil, nil);
|
||||
iResult := WcxModule.WcxProcessFile(ArcHandle, PK_SKIP, EmptyStr, EmptyStr);
|
||||
|
||||
//Check for errors
|
||||
{if iResult <> E_SUCCESS then
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ var
|
|||
begin
|
||||
if (anOpenMode >= PK_OM_LIST) and (anOpenMode <= PK_OM_EXTRACT) then
|
||||
begin
|
||||
{if Assigned(OpenArchiveW) then
|
||||
if Assigned(OpenArchiveW) then
|
||||
begin
|
||||
FillChar(ArcFileW, SizeOf(ArcFileW), #0);
|
||||
WideFileName := UTF8Decode(FileName);
|
||||
|
|
@ -198,7 +198,7 @@ begin
|
|||
else
|
||||
OpenResult := E_SUCCESS;
|
||||
end
|
||||
else} if Assigned(OpenArchive) then
|
||||
else if Assigned(OpenArchive) then
|
||||
begin
|
||||
FillChar(ArcFile, SizeOf(ArcFile), #0);
|
||||
AnsiFileName := UTF8ToSys(FileName);
|
||||
|
|
@ -217,22 +217,52 @@ end;
|
|||
|
||||
function TWCXModule.WcxProcessFile(hArcData: TArcHandle; Operation: LongInt;
|
||||
DestPath, DestName: UTF8String): LongInt;
|
||||
var
|
||||
pwcDestPath: PWideChar;
|
||||
pacDestPath: PAnsiChar;
|
||||
begin
|
||||
if Assigned(ProcessFileW) then
|
||||
Result:= ProcessFileW(hArcData, Operation, PWideChar(UTF8Decode(DestPath)), PWideChar(UTF8Decode(DestName)))
|
||||
begin
|
||||
if DestPath = EmptyStr then
|
||||
pwcDestPath:= nil
|
||||
else
|
||||
pwcDestPath:= PWideChar(UTF8Decode(DestPath));
|
||||
Result:= ProcessFileW(hArcData, Operation, pwcDestPath, PWideChar(UTF8Decode(DestName)));
|
||||
end
|
||||
else if Assigned(ProcessFile) then
|
||||
Result:= ProcessFile(hArcData, Operation, PAnsiChar(UTF8ToSys(DestPath)), PAnsiChar(UTF8ToSys(DestName)));
|
||||
begin
|
||||
if DestPath = EmptyStr then
|
||||
pacDestPath:= nil
|
||||
else
|
||||
pacDestPath:= PAnsiChar(UTF8ToSys(DestPath));
|
||||
Result:= ProcessFile(hArcData, Operation, pacDestPath, PAnsiChar(UTF8ToSys(DestName)));
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWCXModule.WcxPackFiles(PackedFile, SubPath, SrcPath,
|
||||
AddList: UTF8String; Flags: LongInt): LongInt;
|
||||
var
|
||||
pwcSubPath: PWideChar;
|
||||
pacSubPath: PAnsiChar;
|
||||
begin
|
||||
if Assigned(PackFilesW) then
|
||||
Result:= PackFilesW(PWideChar(UTF8Decode(PackedFile)), PWideChar(UTF8Decode(SubPath)),
|
||||
PWideChar(UTF8Decode(SrcPath)), PWideChar(UTF8Decode(AddList)), Flags)
|
||||
begin
|
||||
if SubPath = EmptyStr then
|
||||
pwcSubPath:= nil
|
||||
else
|
||||
pwcSubPath:= PWideChar(UTF8Decode(SubPath));
|
||||
Result:= PackFilesW(PWideChar(UTF8Decode(PackedFile)), pwcSubPath,
|
||||
PWideChar(UTF8Decode(SrcPath)), PWideChar(UTF8Decode(AddList)), Flags);
|
||||
end
|
||||
else if Assigned(PackFiles) then
|
||||
Result:= PackFiles(PAnsiChar(UTF8ToSys(PackedFile)), PAnsiChar(UTF8ToSys(SubPath)),
|
||||
PAnsiChar(UTF8ToSys(SrcPath)), PAnsiChar(UTF8ToSys(AddList)), Flags)
|
||||
begin
|
||||
if SubPath = EmptyStr then
|
||||
pacSubPath:= nil
|
||||
else
|
||||
pacSubPath:= PAnsiChar(UTF8ToSys(SubPath));
|
||||
Result:= PackFiles(PAnsiChar(UTF8ToSys(PackedFile)), pacSubPath,
|
||||
PAnsiChar(UTF8ToSys(SrcPath)), PAnsiChar(UTF8ToSys(AddList)), Flags);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TWCXModule.WcxDeleteFiles(PackedFile, DeleteList: UTF8String): LongInt;
|
||||
|
|
@ -446,7 +476,7 @@ var
|
|||
begin
|
||||
HeaderData := nil;
|
||||
|
||||
{if Assigned(ReadHeaderExW) then
|
||||
if Assigned(ReadHeaderExW) then
|
||||
begin
|
||||
FillChar(ArcHeaderExW, SizeOf(ArcHeaderExW), #0);
|
||||
Result := ReadHeaderExW(hArcData, ArcHeaderExW);
|
||||
|
|
@ -455,7 +485,7 @@ begin
|
|||
HeaderData := TWCXHeader.Create(PHeaderDataExW(@ArcHeaderExW));
|
||||
end;
|
||||
end
|
||||
else} if Assigned(ReadHeaderEx) then
|
||||
else if Assigned(ReadHeaderEx) then
|
||||
begin
|
||||
FillChar(ArcHeaderEx, SizeOf(ArcHeaderEx), #0);
|
||||
Result := ReadHeaderEx(hArcData, ArcHeaderEx);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue