mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-06 15:58:37 +02:00
457 lines
11 KiB
ObjectPascal
457 lines
11 KiB
ObjectPascal
unit Unit1;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
|
|
ExtCtrls, Buttons, Menus, LCLIntf, LazFileUtils, PotFile;
|
|
|
|
type
|
|
|
|
{ TForm1 }
|
|
|
|
TForm1 = class(TForm)
|
|
chkSearchPoItemIgnoreUnit: TCheckBox;
|
|
chkSearchPoItemIdText: TCheckBox;
|
|
chkSearchPoItemFullWord: TCheckBox;
|
|
edSearchPoItems: TEdit;
|
|
lbPoFiles: TListBox;
|
|
lbPoItems: TListBox;
|
|
memInfo: TMemo;
|
|
mnDupIgnCase: TMenuItem;
|
|
mnDupIgnoreSpaceDiff: TMenuItem;
|
|
OpenDialog1: TOpenDialog;
|
|
Panel1: TPanel;
|
|
pnlSearch: TPanel;
|
|
btnClearSearchPoItem: TSpeedButton;
|
|
popMoveTo: TPopupMenu;
|
|
popDupFinder: TPopupMenu;
|
|
Splitter1: TSplitter;
|
|
Splitter2: TSplitter;
|
|
Timer1: TTimer;
|
|
ToolBar1: TToolBar;
|
|
ToolButton1: TToolButton;
|
|
tbMovePoItems: TToolButton;
|
|
tbSave: TToolButton;
|
|
tbDupId: TToolButton;
|
|
ToolButton2: TToolButton;
|
|
ToolButton3: TToolButton;
|
|
tbShowMsgIdEntries: TToolButton;
|
|
tbShowPoFileInfo: TToolButton;
|
|
procedure btnClearSearchPoItemClick(Sender: TObject);
|
|
procedure chkSearchPoItemFullWordChange(Sender: TObject);
|
|
procedure edSearchPoItemsChange(Sender: TObject);
|
|
procedure edSearchPoItemsEditingDone(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDropFiles(Sender: TObject; const FileNames: array of string);
|
|
procedure lbPoFilesClick(Sender: TObject);
|
|
procedure lbPoItemsClick(Sender: TObject);
|
|
procedure tbDupIdClick(Sender: TObject);
|
|
procedure tbSaveClick(Sender: TObject);
|
|
procedure tbShowMsgIdEntriesClick(Sender: TObject);
|
|
procedure Timer1Timer(Sender: TObject);
|
|
procedure ToolButton1Click(Sender: TObject);
|
|
private
|
|
FPotList: TPotFileList;
|
|
FCurPotFile: TPotFile;
|
|
FInbPoFilesClick: Boolean;
|
|
FDupIdPotFile: TPotFile;
|
|
|
|
function AddFile(AFileName: String): TPotFile;
|
|
procedure OnMoveClicked(Sender: TObject);
|
|
procedure SetCurrentFile(ACurPotFile: TPotFile);
|
|
procedure UpdateSaveButton;
|
|
procedure UpdatePoItems;
|
|
procedure UpdatePoItemFiles;
|
|
procedure UpdatePotItems;
|
|
public
|
|
destructor Destroy; override;
|
|
|
|
end;
|
|
|
|
var
|
|
Form1: TForm1;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TForm1 }
|
|
|
|
procedure TForm1.ToolButton1Click(Sender: TObject);
|
|
var
|
|
f: TPotFile;
|
|
begin
|
|
if OpenDialog1.Execute then begin
|
|
f := AddFile(OpenDialog1.FileName);
|
|
SetCurrentFile(f);
|
|
end;
|
|
end;
|
|
|
|
function TForm1.AddFile(AFileName: String): TPotFile;
|
|
var
|
|
m: TMenuItem;
|
|
i: Integer;
|
|
begin
|
|
for i := 0 to lbPoFiles.Count - 1 do
|
|
if TPotFile(lbPoFiles.Items.Objects[i]).FileName = AFileName then
|
|
exit;
|
|
|
|
Result := TPotFile.Create(AFileName);
|
|
lbPoFiles.AddItem(Format('%s (%d)', [Result.Name, Result.Count]), Result);
|
|
|
|
FPotList.Add(Result);
|
|
|
|
m := TMenuItem.Create(popMoveTo);
|
|
m.Caption := Result.Name;
|
|
m.Tag := PtrInt(Result);
|
|
m.OnClick := @OnMoveClicked;
|
|
popMoveTo.Items.Add(m);
|
|
end;
|
|
|
|
procedure TForm1.OnMoveClicked(Sender: TObject);
|
|
var
|
|
target: TPotFile;
|
|
i, j, e: Integer;
|
|
itm, newItm: TPotSection;
|
|
po, targetPo: TPoFile;
|
|
entry, newEntry: TPoSection;
|
|
prefix: String;
|
|
begin
|
|
target := TPotFile(TMenuItem(Sender).Tag);
|
|
|
|
prefix := '';
|
|
if target.Count > 1 then
|
|
prefix := target.Items[1].VarNameUnit;
|
|
if prefix = '' then
|
|
prefix := LowerCase(target.Name);
|
|
if not InputQuery('Move items', 'Enter the Unit-name used in the target file:', prefix) then
|
|
exit;
|
|
|
|
for i := 0 to lbPoItems.Count - 1 do begin
|
|
if not lbPoItems.Selected[i] then
|
|
continue;
|
|
|
|
itm := TPotSection(lbPoItems.Items.Objects[i]);
|
|
|
|
newItm := TPotSection.Create;
|
|
newItm.Text := itm.Text;
|
|
newItm.DeleteMsgCtxt;
|
|
newItm.ReplaceUnitPrefix(prefix);
|
|
target.Add(newItm);
|
|
|
|
for j := 0 to FCurPotFile.PoFiles.Count - 1 do begin
|
|
po := FCurPotFile.PoFiles[j];
|
|
e := po.IndexOfVar(itm.VarName);
|
|
if e < 0 then
|
|
Continue;
|
|
|
|
entry := po.Items[e];
|
|
targetPo := target.PoFiles.PoFileForLang(po.LangName, True);
|
|
newEntry := TPoSection.Create;
|
|
newEntry.Text := entry.Text;
|
|
newEntry.DeleteMsgCtxt;
|
|
newEntry.ReplaceUnitPrefix(prefix);
|
|
targetPo.Add(newEntry);
|
|
|
|
po.Remove(entry);
|
|
end;
|
|
|
|
FCurPotFile.Remove(itm);
|
|
end;
|
|
|
|
FCurPotFile.SetModified;
|
|
target.SetModified;
|
|
UpdateSaveButton;
|
|
UpdatePotItems;
|
|
UpdatePoItems;
|
|
end;
|
|
|
|
procedure TForm1.SetCurrentFile(ACurPotFile: TPotFile);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
FCurPotFile := ACurPotFile;
|
|
|
|
i := lbPoFiles.Items.IndexOfObject(ACurPotFile);
|
|
if i > 0 then
|
|
lbPoFiles.ItemIndex := i;
|
|
UpdatePoItems;
|
|
|
|
UpdateSaveButton;
|
|
|
|
for i := 0 to popMoveTo.Items.Count - 1 do
|
|
popMoveTo.Items[i].Enabled := popMoveTo.Items[i].Tag <> PtrInt(FCurPotFile);
|
|
end;
|
|
|
|
procedure TForm1.UpdateSaveButton;
|
|
begin
|
|
tbSave.Enabled := (FCurPotFile <> nil) and FCurPotFile.Modified;
|
|
if FCurPotFile <> nil then
|
|
tbSave.Caption := format('Save %s', [FCurPotFile.Name]);
|
|
end;
|
|
|
|
procedure TForm1.UpdatePoItems;
|
|
function HasWord(AWord, AText: String): Boolean;
|
|
var
|
|
i: SizeInt;
|
|
begin
|
|
i := Pos(AWord, AText);
|
|
Result := (i > 0) and
|
|
( (i = 1) or not (AText[i-1] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) ) and
|
|
( (i + Length(AWord) > Length(AText)) or not (AText[i + Length(AWord)] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) )
|
|
;
|
|
end;
|
|
var
|
|
i, j, CntAll, CntNoneEmpty: Integer;
|
|
itm: TPotSection;
|
|
MatchWords, MatchTxtId, fnd, MatchIgnUName: Boolean;
|
|
t: String;
|
|
FindTerms: TStringArray;
|
|
begin
|
|
Timer1.Enabled := False;
|
|
if tbShowPoFileInfo.Down then begin
|
|
UpdatePoItemFiles;
|
|
exit;
|
|
end;
|
|
|
|
lbPoItems.Clear;
|
|
if FCurPotFile = nil then
|
|
exit;
|
|
|
|
// Start at 1, Item 0 is the header
|
|
t := lowercase(edSearchPoItems.Text);
|
|
FindTerms := t.Split(',');
|
|
for j := Length(FindTerms) - 1 downto 0 do begin
|
|
FindTerms[j] := Trim(FindTerms[j]);
|
|
if FindTerms[j] = '' then
|
|
Delete(FindTerms, j, 1);
|
|
end;
|
|
MatchWords := chkSearchPoItemFullWord.Checked;
|
|
MatchIgnUName := chkSearchPoItemIgnoreUnit.Checked;
|
|
MatchTxtId := chkSearchPoItemIdText.Checked;
|
|
lbPoItems.Items.BeginUpdate;
|
|
for i := 1 to FCurPotFile.Count - 1 do begin
|
|
itm := FCurPotFile.Items[i];
|
|
|
|
if Length(FindTerms) > 0 then begin
|
|
fnd := False;
|
|
for j := 0 to Length(FindTerms) - 1 do begin
|
|
if MatchWords then begin
|
|
if MatchIgnUName
|
|
then fnd := HasWord(itm.VarNameIdent, FindTerms[j])
|
|
else fnd := HasWord(itm.VarNameContent, FindTerms[j]);
|
|
end
|
|
else begin
|
|
if MatchIgnUName
|
|
then fnd := Pos(FindTerms[j], itm.VarNameIdent) > 0
|
|
else fnd := Pos(FindTerms[j], itm.VarNameContent) > 0;
|
|
end;
|
|
if fnd then
|
|
break;
|
|
if MatchTxtId then begin
|
|
if MatchWords
|
|
then fnd := HasWord(itm.MsgIdCleanContent, FindTerms[j])
|
|
else fnd := Pos(FindTerms[j], LowerCase(itm.MsgIdCleanContent)) > 0;
|
|
if fnd then
|
|
break;
|
|
end;
|
|
end;
|
|
|
|
if not fnd then
|
|
continue;
|
|
end;
|
|
|
|
//itm.GetTranslationyCount(CntAll, CntNoneEmpty);
|
|
//lbPoItems.AddItem(Format('%s (%d / %d): %s', [itm.MsgIdContent, CntNoneEmpty, CntAll, itm.VarNameContent]), itm);
|
|
lbPoItems.AddItem(Format('%s (%s)', [itm.MsgIdContent, itm.VarNameContent]), itm);
|
|
end;
|
|
lbPoItems.Items.EndUpdate;
|
|
|
|
lbPoItemsClick(nil);
|
|
end;
|
|
|
|
procedure TForm1.UpdatePoItemFiles;
|
|
var
|
|
i: Integer;
|
|
po: TPoFile;
|
|
begin
|
|
lbPoItems.Clear;
|
|
if FCurPotFile = nil then
|
|
exit;
|
|
|
|
for i := 1 to FCurPotFile.PoFiles.Count - 1 do begin
|
|
po := FCurPotFile.PoFiles[i];
|
|
lbPoItems.AddItem(Format('%s (%d / %d)', [po.LangName, po.NoneEmptyCount, po.Count-1]), po);
|
|
end;
|
|
end;
|
|
|
|
procedure TForm1.UpdatePotItems;
|
|
var
|
|
i: Integer;
|
|
pot: TPotFile;
|
|
begin
|
|
for i := 0 to lbPoFiles.Count - 1 do begin
|
|
pot := TPotFile(lbPoFiles.Items.Objects[i]);
|
|
if pot.Modified
|
|
then lbPoFiles.Items[i] := Format('* %s (%d)', [pot.Name, pot.Count - 1])
|
|
else lbPoFiles.Items[i] := Format('%s (%d)', [pot.Name, pot.Count - 1]);
|
|
end;
|
|
end;
|
|
|
|
destructor TForm1.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
FDupIdPotFile.Free;
|
|
FPotList.Free;
|
|
end;
|
|
|
|
procedure TForm1.FormDropFiles(Sender: TObject; const FileNames: array of string
|
|
);
|
|
var
|
|
s: String;
|
|
f: TPotFile;
|
|
begin
|
|
f := nil;
|
|
for s in FileNames do
|
|
f := AddFile(s);
|
|
SetCurrentFile(f);
|
|
end;
|
|
|
|
procedure TForm1.btnClearSearchPoItemClick(Sender: TObject);
|
|
begin
|
|
if (edSearchPoItems.Text = '') and not Timer1.Enabled then
|
|
exit;
|
|
edSearchPoItems.Clear;
|
|
if tbShowMsgIdEntries.Down then
|
|
UpdatePoItems;
|
|
end;
|
|
|
|
procedure TForm1.chkSearchPoItemFullWordChange(Sender: TObject);
|
|
begin
|
|
if (edSearchPoItems.Text = '') and not Timer1.Enabled then
|
|
exit;
|
|
if tbShowMsgIdEntries.Down then
|
|
UpdatePoItems;
|
|
end;
|
|
|
|
procedure TForm1.edSearchPoItemsChange(Sender: TObject);
|
|
begin
|
|
if tbShowPoFileInfo.Down then
|
|
exit;
|
|
Timer1.Enabled := False;
|
|
Timer1.Enabled := True;
|
|
end;
|
|
|
|
procedure TForm1.edSearchPoItemsEditingDone(Sender: TObject);
|
|
begin
|
|
if tbShowMsgIdEntries.Down then
|
|
UpdatePoItems;
|
|
end;
|
|
|
|
procedure TForm1.FormCreate(Sender: TObject);
|
|
begin
|
|
FPotList := TPotFileList.Create;
|
|
end;
|
|
|
|
procedure TForm1.lbPoFilesClick(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
begin
|
|
if FInbPoFilesClick then
|
|
exit;
|
|
|
|
i := lbPoFiles.ItemIndex;
|
|
if i < 0 then
|
|
exit;
|
|
FInbPoFilesClick := True;
|
|
SetCurrentFile(TPotFile(lbPoFiles.Items.Objects[i]));
|
|
FInbPoFilesClick := False;
|
|
end;
|
|
|
|
procedure TForm1.lbPoItemsClick(Sender: TObject);
|
|
var
|
|
i, j, cnt: Integer;
|
|
itm: TPotSection;
|
|
s: String;
|
|
po: TPoFile;
|
|
e: LongInt;
|
|
begin
|
|
if not tbShowMsgIdEntries.Down then
|
|
exit;
|
|
memInfo.Clear;
|
|
cnt := 0;
|
|
for i := 0 to lbPoItems.Count - 1 do begin
|
|
if not lbPoItems.Selected[i] then
|
|
continue;
|
|
|
|
inc(cnt);
|
|
if not (lbPoItems.Items.Objects[i] is TPotSection) then
|
|
continue;
|
|
itm := TPotSection(lbPoItems.Items.Objects[i]);
|
|
//itmid := itm.MsgId;
|
|
s := itm.VarName + LineEnding;
|
|
s := s + itm.MsgId + LineEnding;
|
|
s := s + itm.MsgStr + LineEnding;
|
|
for j := 0 to FCurPotFile.PoFiles.Count - 1 do begin
|
|
po := FCurPotFile.PoFiles[j];
|
|
e := po.IndexOfVar(itm.VarName);
|
|
if e >= 0 then begin
|
|
s := s + po.LangName + ': ' + po.Items[e].MsgStr + LineEnding;
|
|
end;
|
|
end;
|
|
|
|
s := s + LineEnding;
|
|
memInfo.Append(s);
|
|
end;
|
|
|
|
tbMovePoItems.Enabled := cnt > 0;
|
|
tbMovePoItems.Caption := format('Move %d items to', [cnt]);
|
|
end;
|
|
|
|
procedure TForm1.tbDupIdClick(Sender: TObject);
|
|
var
|
|
fl: TFindDupFlags;
|
|
begin
|
|
if FDupIdPotFile = nil then begin
|
|
FDupIdPotFile := TPotFile.Create('', True);
|
|
lbPoFiles.AddItem('Dups', FDupIdPotFile);
|
|
end;
|
|
|
|
fl := [];
|
|
if mnDupIgnCase.Checked then
|
|
Include(fl, fdIgnoreCase);
|
|
if mnDupIgnoreSpaceDiff.Checked then
|
|
Include(fl, fdIgnoreSpaceDiff);
|
|
|
|
FPotList.FindDuplicateMsgId(FDupIdPotFile, fl);
|
|
|
|
UpdatePotItems;
|
|
SetCurrentFile(FDupIdPotFile);
|
|
end;
|
|
|
|
procedure TForm1.tbSaveClick(Sender: TObject);
|
|
begin
|
|
if FCurPotFile = nil then
|
|
exit;
|
|
|
|
FCurPotFile.Save;
|
|
UpdatePotItems;
|
|
tbSave.Enabled := False;
|
|
end;
|
|
|
|
procedure TForm1.tbShowMsgIdEntriesClick(Sender: TObject);
|
|
begin
|
|
UpdatePoItems;
|
|
end;
|
|
|
|
procedure TForm1.Timer1Timer(Sender: TObject);
|
|
begin
|
|
UpdatePoItems;
|
|
end;
|
|
|
|
end.
|
|
|