ADD: Processing file comments

This commit is contained in:
Alexander Koblov 2008-08-26 09:31:37 +00:00
commit cbd3d2b699
10 changed files with 340 additions and 10 deletions

View file

@ -49,7 +49,7 @@
<PackageName Value="imagesforlazarus"/>
</Item5>
</RequiredPackages>
<Units Count="34">
<Units Count="35">
<Unit0>
<Filename Value="doublecmd.lpr"/>
<IsPartOfProject Value="True"/>
@ -319,6 +319,11 @@
<ResourceFilename Value="ftweakplugin.lrs"/>
<UnitName Value="fTweakPlugin"/>
</Unit33>
<Unit34>
<Filename Value="udescr.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="uDescr"/>
</Unit34>
</Units>
</ProjectOptions>
<CompilerOptions>

View file

@ -60,7 +60,7 @@ uses
uPixMapManager, uVFS, fFileAssoc,
KASComp, fconfigtoolbar, uWCXprototypes, uDCUtils, uOSUtils,
dmDialogs, fViewer, fOptions, fCopyDlg, fMoveDlg, fFindDlg,
fSymLink, fMultiRename, fSplitter, fPackDlg, fExtractDlg;
fSymLink, fMultiRename, fSplitter, fPackDlg, fExtractDlg, uDescr;
{$IFDEF MSWINDOWS}
{$R XP.res}

View file

@ -30,7 +30,8 @@ type
implementation
uses
LCLProc, SysUtils, Classes, uLng, uGlobs, uLog, uShowMsg, uFileProcs, uFindEx, uDCUtils, uOSUtils, uClassesEx;
LCLProc, SysUtils, Classes, uLng, uGlobs, uLog, uShowMsg, uFileProcs, uFindEx,
uDCUtils, uOSUtils, uClassesEx, uDescr;
procedure TCopyThread.MainExecute;
var
@ -44,6 +45,7 @@ begin
FReplaceAll:=False;
FSkipAll:=False;
iCoped:=0;
for xIndex:=0 to NewFileList.Count-1 do // copy
begin
if Terminated then
@ -70,6 +72,7 @@ begin
FFileOpDlg.iProgress2Pos:=iCoped;
Synchronize(@FFileOpDlg.UpdateDlg);
end;
// writeln('iCoped:',iCoped,' FFileSize', FFilesSize);
end;
@ -138,6 +141,10 @@ begin
end;
Result:=CopyFile(fr^.sName, sDst+fr^.sPath+sDstNew, FAppend);
// process comments if need
if Result and gProcessComments and Assigned(FDescr) then
FDescr.CopyDescription(fr^.sName, sDst+fr^.sPath+sDstNew);
if Result then
// write log success
if (log_cp_mv_ln in gLogOptions) and (log_success in gLogOptions) then

View file

@ -89,6 +89,9 @@ begin
logWrite(Self, Format(rsMsgLogError+rsMsgLogDelete, [fr^.sName]), lmtError);
end;
// process comments if need
if Result and gProcessComments and Assigned(FDescr) then
FDescr.DeleteDescription(fr^.sName);
except
DebugLN('Can not delete ', fr^.sName);
end;

293
udescr.pas Normal file
View file

@ -0,0 +1,293 @@
{
Double commander
-------------------------------------------------------------------------
This unit contains class for working with file comments.
Copyright (C) 2008 Koblov Alexander (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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
unit uDescr;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, uClassesEx;
type
{ TDescription }
TDescription = class(TStringListEx)
private
FLastDescrFile: String;
FDestDescr: TDescription;
procedure PrepareDescrFile(FileName: String);
function Find(const S: string; var Index: Integer): Boolean; override;
function GetDescription(Index: Integer): String;
function GetDescription(const FileName: String): String;
procedure SetDescription(Index: Integer; const AValue: String);
procedure SetDescription(const FileName: String; const AValue: String);
public
{en
Create TDescription class
@param(UseSubDescr @true if need Copy/Move functions)
}
constructor Create(UseSubDescr: Boolean);
{en
Destroy TDescription class
}
destructor Destroy; override;
{en
Add description for file
@param(FileName File name)
@param(Descr Description)
@returns(Index of added item)
}
function AddDescription(FileName, Descr: String): Integer;
{en
Read description by file name
@param(FileName File name)
@returns(Description of file)
}
function ReadDescription(FileName: String): String;
{en
Write description for file
@param(FileName File name)
@param(Descr Description)
}
procedure WriteDescription(FileName: String; const Descr: String);
{en
Delete description by file name
@param(FileName File name)
@returns(The function returns @true if successful, @false otherwise)
}
function DeleteDescription(const FileName: String): Boolean;
{en
Copy description for file
@param(FileNameFrom Source file name)
@param(FileNameTo Destination file name)
@returns(The function returns @true if successful, @false otherwise)
}
function CopyDescription(const FileNameFrom, FileNameTo: String): Boolean;
{en
Move description for file
@param(FileNameFrom Source file name)
@param(FileNameTo Destination file name)
@returns(The function returns @true if successful, @false otherwise)
}
function MoveDescription(const FileNameFrom, FileNameTo: String): Boolean;
{en
Save all changes to description file
}
procedure SaveDescription;
{en
Get description by file name
}
property DescrByFileName[const FileName: String]: String read GetDescription write SetDescription;
{en
Get description by file name index
}
property DescrByIndex[Index: Integer]: String read GetDescription write SetDescription;
end;
implementation
uses
LCLProc, uOSUtils;
{ TDescription }
procedure TDescription.PrepareDescrFile(FileName: String);
var
sDescrFile: String;
begin
sDescrFile:= ExtractFilePath(FileName) + 'descript.ion';
if sDescrFile <> FLastDescrFile then
begin
SaveToFile(FLastDescrFile);
FLastDescrFile:= sDescrFile;
if mbFileExists(FLastDescrFile) then
LoadFromFile(FLastDescrFile);
end;
end;
function TDescription.Find(const S: string; var Index: Integer): Boolean;
var
I: Integer;
sFileName: String;
begin
Result:= False;
sFileName:= ExtractFileName(S);
for I:= Count-1 downto 0 do
begin
DebugLn(Self[I]);
if Pos(sFileName, Self[I]) <> 0 then
begin
Index:= I;
Exit(True);
end;
end;
end;
function TDescription.GetDescription(Index: Integer): String;
var
sLine: String;
iDescrStart: Integer;
begin
sLine:= Self[Index];
if Pos(#34, sLine) <> 1 then
begin
iDescrStart:= Pos(#32, sLine);
Result:= Copy(sLine, iDescrStart+1, Length(sLine) - iDescrStart);
end
else
begin
iDescrStart:= Pos(#34#32, sLine);
Result:= Copy(sLine, iDescrStart+1, Length(sLine) - iDescrStart);
end;
end;
function TDescription.GetDescription(const FileName: String): String;
var
I: Integer;
begin
Result:= '';
if Find(FileName, I) then
Result:= GetDescription(I);
end;
procedure TDescription.SetDescription(Index: Integer; const AValue: String);
var
sLine,
sFileName: String;
iDescrStart: Integer;
begin
sLine:= Self[Index];
if Pos('"', sLine) <> 1 then
begin
iDescrStart:= Pos(#32, sLine);
sFileName:= Copy(sLine, 1, iDescrStart);
Self[Index]:= sFileName + AValue;
end
else
begin
iDescrStart:= Pos(#34#32, sLine);
sFileName:= Copy(sLine, 1, iDescrStart+1);
Self[Index]:= sFileName + AValue;
end;
end;
procedure TDescription.SetDescription(const FileName: String;
const AValue: String);
var
I: Integer;
begin
if Find(FileName, I) then
SetDescription(I, AValue)
else
AddDescription(FileName, AValue);
end;
constructor TDescription.Create(UseSubDescr: Boolean);
begin
if UseSubDescr then
FDestDescr:= TDescription.Create(False)
else
FDestDescr:= nil;
inherited Create;
end;
destructor TDescription.Destroy;
begin
if Assigned(FDestDescr) then
FreeAndNil(FDestDescr);
inherited Destroy;
end;
function TDescription.AddDescription(FileName, Descr: String): Integer;
begin
FileName:= ExtractFileName(FileName);
if Pos(#32, FileName) <> 0 then
Add(#34+FileName+#34#32+Descr)
else
Add(FileName+#32+Descr)
end;
function TDescription.ReadDescription(FileName: String): String;
begin
PrepareDescrFile(FileName);
Result:= GetDescription(FileName);
end;
procedure TDescription.WriteDescription(FileName: String; const Descr: String);
begin
PrepareDescrFile(FileName);
SetDescription(FileName, Descr);
end;
function TDescription.DeleteDescription(const FileName: String): Boolean;
var
I: Integer;
begin
Result:= False;
PrepareDescrFile(FileName);
if Find(FileName, I) then
begin
Delete(I);
Result:= True;
end;
end;
function TDescription.CopyDescription(const FileNameFrom, FileNameTo: String): Boolean;
var
I: Integer;
begin
Result:= False;
PrepareDescrFile(FileNameFrom);
if Find(FileNameFrom, I) then
begin
DebugLn(FileNameFrom, '=', DescrByIndex[I]);
FDestDescr.WriteDescription(FileNameTo, DescrByIndex[I]);
Result:= True;
end;
end;
function TDescription.MoveDescription(const FileNameFrom, FileNameTo: String): Boolean;
var
I: Integer;
begin
Result:= False;
PrepareDescrFile(FileNameFrom);
if Find(FileNameFrom, I) then
begin
DebugLn(FileNameFrom, '=', DescrByIndex[I]);
FDestDescr.WriteDescription(FileNameTo, DescrByIndex[I]);
Delete(I);
Result:= True;
end;
end;
procedure TDescription.SaveDescription;
begin
SaveToFile(FLastDescrFile);
if Assigned(FDestDescr) then
FDestDescr.SaveDescription;
end;
end.

View file

@ -19,7 +19,7 @@ unit uFileOpThread;
interface
uses
Classes, uFileList, fFileOpDlg, uTypes, fMsg, uShowMsg {$IFNDEF NOFAKETHREAD}, uFakeThread{$ENDIF};
Classes, uFileList, fFileOpDlg, uTypes, uDescr, fMsg, uShowMsg {$IFNDEF NOFAKETHREAD}, uFakeThread{$ENDIF};
type
{ TFileOpThread }
@ -45,6 +45,7 @@ type
FAppend: Boolean; // used mainly for pass information between move and copy
FSymLinkAll, // process all symlinks
FNotSymLinkAll : Boolean; // process all real files/folders
FDescr: TDescription;
procedure Execute; override;
procedure MainExecute; virtual; abstract; // main loop for copy /delete ...
@ -76,7 +77,8 @@ const
implementation
uses
SysUtils, uLng, uFileProcs, uFileOp, Forms, uFindEx, uDCUtils, uOSUtils, LCLProc;
SysUtils, uLng, uFileProcs, uFileOp, Forms, uFindEx, uDCUtils, uOSUtils,
LCLProc, uGlobs;
{ TFileOpThread }
@ -212,6 +214,9 @@ try
try
FillAndCount; // gets full list of files (rekursive)
if gProcessComments then
FDescr:= TDescription.Create(True);
if UseForm then
begin
//FFileOpDlg:=TfrmFileOp.Create(Application);
@ -233,11 +238,16 @@ try
finally
if UseForm then
begin
Synchronize(@FFileOpDlg.Close);
DebugLN('TFileOpThread finally');
end;
if assigned(NewFileList) then
begin
Synchronize(@FFileOpDlg.Close);
DebugLN('TFileOpThread finally');
end;
if gProcessComments and Assigned(FDescr) then
begin
FDescr.SaveDescription;
FreeAndNil(FDescr);
end;
if Assigned(NewFileList) then
FreeAndNil(NewFileList);
end;
except

View file

@ -145,6 +145,7 @@ var
gCopyBlockSize : Integer;
gDropReadOnlyFlag : Boolean = True;
gWipePassNumber: Integer;
gProcessComments: Boolean;
gRenameSelOnlyName:boolean;
@ -478,6 +479,7 @@ begin
gDropReadOnlyFlag := gIni.ReadBool('Configuration', 'DropReadOnlyFlag', True);
gUseMmapInSearch := gIni.ReadBool('Configuration', 'UseMmapInSearch', False);
gWipePassNumber:= gIni.ReadInteger('Configuration', 'WipePassNumber', 1);
gProcessComments := gIni.ReadBool('Configuration', 'ProcessComments', True);
gRenameSelOnlyName:= gIni.ReadBool('Configuration', 'RenameSelOnlyName', false);
{ Log }
gLogFile := gIni.ReadBool('Configuration', 'LogFile', True);
@ -639,6 +641,7 @@ begin
gIni.WriteBool('Configuration', 'DropReadOnlyFlag', gDropReadOnlyFlag);
gIni.WriteBool('Configuration', 'UseMmapInSearch', gUseMmapInSearch);
gIni.WriteInteger('Configuration', 'WipePassNumber', gWipePassNumber);
gIni.WriteBool('Configuration', 'ProcessComments', gProcessComments);
gIni.WriteBool('Configuration', 'RenameSelOnlyName', gRenameSelOnlyName);
{ Log }
gIni.WriteBool('Configuration', 'LogFile', gLogFile);

View file

@ -119,6 +119,10 @@ begin
end
else
begin // rename succes
// process comments if need
if gProcessComments and Assigned(FDescr) then
FDescr.MoveDescription(pr^.sName, sDstPath+pr^.sPath+ sDstNew);
// write log
if (log_cp_mv_ln in gLogOptions) and (log_success in gLogOptions) then
logWrite(Self, Format(rsMsgLogSuccess+rsMsgLogMove, [pr^.sName+' -> '+sDstPath+pr^.sPath+ sDstNew]), lmtSuccess)
end;

View file

@ -5,3 +5,4 @@ uosforms.pas
uvfs.pas
uexts.pas
ufileprocs.pas
udescr.pas

View file

@ -368,6 +368,10 @@ begin
WipeDir(fr^.sName)
else // files
WipeFile(fr^.sName);
// process comments if need
if gProcessComments and Assigned(FDescr) then
FDescr.DeleteDescription(fr^.sName);
except
DebugLn('Can not wipe ', fr^.sName);
end;