lazarus/components/lazsvnpkg/svnstatusform.pas
juha 77e6853ca6 Components: Reduce calls to LowerCase().
git-svn-id: trunk@64515 -
2021-02-10 13:43:15 +00:00

456 lines
13 KiB
ObjectPascal

{ Copyright (C) 2008 Darius Blaszijk
This source 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 code 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.
A copy of the GNU General Public License is available on the World Wide Web
at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
Boston, MA 02110-1335, USA.
}
unit SVNStatusForm;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Process, LCLProc,
Forms, Controls, Dialogs, ComCtrls, StdCtrls, ButtonPanel, ExtCtrls, Menus,
// LazUtils
FileUtil, LazFileUtils, LazConfigStorage, UTF8Process,
// IDEIntf
LazIDEIntf, BaseIDEIntf,
// LazSvn
SVNClasses;
type
{ TSVNStatusFrm }
TSVNStatusFrm = class(TForm)
ButtonPanel: TButtonPanel;
CommitMsgHistoryLabel: TLabel;
CommitMsgLabel: TLabel;
Panel1: TPanel;
ImageList: TImageList;
mnuOpen: TMenuItem;
mnuRemove: TMenuItem;
mnuAdd: TMenuItem;
mnuRevert: TMenuItem;
mnuShowDiff: TMenuItem;
PopupMenu1: TPopupMenu;
Splitter: TSplitter;
SVNCommitMsgHistoryComboBox: TComboBox;
SVNCommitMsgMemo: TMemo;
SVNFileListView: TListView;
procedure CancelButtonClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure mnuAddClick(Sender: TObject);
procedure mnuOpenClick(Sender: TObject);
procedure mnuRemoveClick(Sender: TObject);
procedure mnuRevertClick(Sender: TObject);
procedure mnuShowDiffClick(Sender: TObject);
procedure OKButtonClick(Sender: TObject);
procedure PatchButtonClick(Sender: TObject);
procedure PopupMenu1Popup(Sender: TObject);
procedure SVNCommitMsgHistoryComboBoxChange(Sender: TObject);
procedure SVNFileListViewColumnClick(Sender: TObject; Column: TListColumn);
private
FRepositoryPath: string;
SVNStatus: TSVNStatus;
procedure Initialize({%H-}Data: PtrInt);
procedure ExecuteSvnCommand(ACommand: String; AFile: String);
procedure UpdateFilesListView;
procedure ChangeCursor(ACursor: TCursor);
procedure UpdateCheckedStatus;
public
{path the root of the local working copy}
property RepositoryPath: string read FRepositoryPath write FRepositoryPath;
end;
procedure ShowSVNStatusFrm(ARepoPath: string);
var
SVNStatusFrm: TSVNStatusFrm;
implementation
{$R *.lfm}
uses
SVNDiffForm, SVNCommitForm;
procedure ShowSVNStatusFrm(ARepoPath: string);
begin
if not Assigned(SVNStatusFrm) then
SVNStatusFrm := TSVNStatusFrm.Create(nil);
SVNStatusFrm.ChangeCursor(crHourGlass);
SVNStatusFrm.RepositoryPath:=ARepoPath;
SVNStatusFrm.Show;
end;
{ TSVNStatusFrm }
procedure TSVNStatusFrm.FormShow(Sender: TObject);
begin
Caption := Format('%s - %s ...', [RepositoryPath, rsLazarusSVNCommit]);
CommitMsgHistoryLabel.Caption:=rsCommitMsgHistory;
CommitMsgLabel.Caption:=rsCommitMsg;
Application.QueueAsyncCall(@Initialize, 0);
end;
procedure TSVNStatusFrm.Initialize(Data: PtrInt);
begin
SVNStatus := TSVNStatus.Create(RepositoryPath, false);
SVNStatus.Sort(siChecked, sdAscending);
UpdateFilesListView;
ChangeCursor(crDefault);
end;
procedure TSVNStatusFrm.mnuRevertClick(Sender: TObject);
begin
if Assigned(SVNFileListView.Selected) then
begin
ExecuteSvnCommand('revert', SVNFileListView.Selected.SubItems[0]);
//now delete the entry from the list
SVNStatus.List.Delete(SVNFileListView.Selected.Index);
//update the listview again
UpdateFilesListView;
end;
end;
procedure TSVNStatusFrm.mnuAddClick(Sender: TObject);
begin
if Assigned(SVNFileListView.Selected) then
begin
ExecuteSvnCommand('add', SVNFileListView.Selected.SubItems[0]);
// completely re-read the status
SVNStatus.Free;
SVNStatus := TSVNStatus.Create(RepositoryPath, false);
SVNStatus.Sort(siChecked, sdAscending);
UpdateFilesListView;
end;
end;
procedure TSVNStatusFrm.mnuOpenClick(Sender: TObject);
var
FileName: String;
begin
if Assigned(SVNFileListView.Selected) then
begin
FileName := CreateAbsolutePath(SVNFileListView.Selected.SubItems[0], RepositoryPath);
LazarusIDE.DoOpenEditorFile(FileName, -1, -1, [ofOnlyIfExists]);
end;
end;
procedure TSVNStatusFrm.mnuRemoveClick(Sender: TObject);
begin
if Assigned(SVNFileListView.Selected) then
begin
ExecuteSvnCommand('remove --keep-local', SVNFileListView.Selected.SubItems[0]);
// completely re-read the status
SVNStatus.Free;
SVNStatus := TSVNStatus.Create(RepositoryPath, false);
SVNStatus.Sort(siChecked, sdAscending);
UpdateFilesListView;
end;
end;
procedure TSVNStatusFrm.ExecuteSvnCommand(ACommand: String; AFile: String);
var
AProcess: TProcessUTF8;
begin
AProcess := TProcessUTF8.Create(nil);
if pos(RepositoryPath, AFile) <> 0 then
AProcess.CommandLine := SVNExecutable + ' ' + ACommand + ' "' + AFile + '"'
else
AProcess.CommandLine := SVNExecutable + ' ' + ACommand + ' "' + AppendPathDelim(RepositoryPath) + AFile + '"';
debugln('TSVNStatusFrm.ExecuteSvnCommand commandline=', AProcess.CommandLine);
AProcess.Options := AProcess.Options + [poWaitOnExit];
AProcess.ShowWindow := swoHIDE;
AProcess.Execute;
AProcess.Free;
end;
procedure TSVNStatusFrm.mnuShowDiffClick(Sender: TObject);
begin
if Assigned(SVNFileListView.Selected) then
begin
debugln('TSVNStatusFrm.mnuShowDiffClick Path=' ,SVNFileListView.Selected.SubItems[0]);
if pos(RepositoryPath,SVNFileListView.Selected.SubItems[0]) <> 0 then
ShowSVNDiffFrm('-r BASE', SVNFileListView.Selected.SubItems[0])
else
ShowSVNDiffFrm('-r BASE', AppendPathDelim(RepositoryPath) + SVNFileListView.Selected.SubItems[0]);
end;
end;
procedure TSVNStatusFrm.OKButtonClick(Sender: TObject);
var
i: integer;
CmdLine: string;
StatusItem : TSVNStatusItem;
FileName: string;
begin
UpdateCheckedStatus;
if SVNCommitMsgMemo.Text = '' then
if MessageDlg ('No message set.', 'Do you wish to continue?', mtConfirmation,
[mbYes, mbNo],0) <> mrYes then
exit;
//commit the checked files
CmdLine := SVNExecutable + ' commit --non-interactive --force-log ';
for i := 0 to SVNStatus.List.Count - 1 do
begin
StatusItem := SVNStatus.List[i];
if StatusItem.Checked then
if pos(RepositoryPath,StatusItem.Path) = 0 then
CmdLine := CmdLine + ' "' + AppendPathDelim(RepositoryPath) + StatusItem.Path + '"'
else
CmdLine := CmdLine + ' "' + StatusItem.Path + '"';
end;
FileName := GetTempFileNameUTF8('','');
SVNCommitMsgMemo.Lines.SaveToFile(FileName);
CmdLine := CmdLine + ' --file ' + FileName;
ShowSVNCommitFrm(CmdLine);
DeleteFile(FileName);
Close;
end;
procedure TSVNStatusFrm.PatchButtonClick(Sender: TObject);
var
i: Integer;
StatusItem: TSVNStatusItem;
FileNames: TStringList;
begin
UpdateCheckedStatus;
Filenames := TStringList.Create;
FileNames.Sorted := True;
for i := 0 to SVNStatus.List.Count - 1 do
begin
StatusItem := SVNStatus.List.Items[i];
if StatusItem.Checked then
if pos(RepositoryPath,StatusItem.Path) = 0 then
FileNames.Append(AppendPathDelim(RepositoryPath) + StatusItem.Path)
else
FileNames.Append(StatusItem.Path);
end;
ShowSVNDiffFrm('-r BASE', FileNames);
end;
procedure TSVNStatusFrm.PopupMenu1Popup(Sender: TObject);
var
P: TPoint;
LI: TListItem;
begin
// make sure the row under the mouse is selected
P := SVNFileListView.ScreenToControl(Mouse.CursorPos);
LI := SVNFileListView.GetItemAt(P.X, P.Y);
if LI <> nil then begin
SVNFileListView.Selected := LI;
{$note: using hardcoded column index!}
if LI.SubItems[2] = 'unversioned' then
mnuRevert.Enabled := False
else
mnuRevert.Enabled := True;
if (LI.SubItems[2] = 'unversioned') or (LI.SubItems[2] = 'deleted') then begin
mnuShowDiff.Enabled := False;
mnuRemove.Enabled := False;
mnuAdd.Enabled := True;
end else begin
mnuShowDiff.Enabled := True;
mnuRemove.Enabled := True;
mnuAdd.Enabled := False;
end;
end;
end;
procedure TSVNStatusFrm.SVNCommitMsgHistoryComboBoxChange(Sender: TObject);
begin
with SVNCommitMsgHistoryComboBox do
if ItemIndex > -1 then
SVNCommitMsgMemo.Text := Items[ItemIndex];
end;
procedure TSVNStatusFrm.SVNFileListViewColumnClick(Sender: TObject;
Column: TListColumn);
begin
case Column.Index of
0: SVNStatus.ReverseSort(siChecked);
1: SVNStatus.ReverseSort(siPath);
2: SVNStatus.ReverseSort(siExtension);
3: SVNStatus.ReverseSort(siItemStatus);
4: SVNStatus.ReverseSort(siPropStatus);
5: SVNStatus.ReverseSort(siAuthor);
6: SVNStatus.ReverseSort(siRevision);
7: SVNStatus.ReverseSort(siCommitRevision);
8: SVNStatus.ReverseSort(siDate);
end;
UpdateFilesListView;
end;
procedure TSVNStatusFrm.UpdateFilesListView;
var
i: integer;
StatusItem : TSVNStatusItem;
Path: string;
begin
SVNFileListView.BeginUpdate;
SVNFileListView.Clear;
for i := 0 to SVNStatus.List.Count - 1 do
begin
with SVNFileListView.Items.Add do
begin
StatusItem := SVNStatus.List.Items[i];
//checkboxes
Caption := '';
Checked := StatusItem.Checked;
//path
Path := StatusItem.Path;
if pos(RepositoryPath, Path) = 1 then
path := CreateRelativePath(path, RepositoryPath, false);
SubItems.Add(Path);
//extension
SubItems.Add(StatusItem.Extension);
//file status
SubItems.Add(StatusItem.ItemStatus);
//property status
SubItems.Add(StatusItem.PropStatus);
//check if file is versioned
if (CompareText(StatusItem.ItemStatus, 'unversioned') <> 0) and
(CompareText(StatusItem.ItemStatus, 'added') <> 0) then
begin
//revision
SubItems.Add(IntToStr(StatusItem.Revision));
//commit revision
SubItems.Add(IntToStr(StatusItem.CommitRevision));
//author
SubItems.Add(StatusItem.Author);
//date
SubItems.Add(DateTimeToStr(StatusItem.Date));
end;
end;
end;
SVNFileListView.EndUpdate;
end;
procedure TSVNStatusFrm.ChangeCursor(ACursor: TCursor);
begin
Cursor := ACursor;
SVNCommitMsgMemo.Cursor := ACursor;
SVNFileListView.Cursor := ACursor;
Self.Cursor := ACursor;
Application.ProcessMessages;
end;
procedure TSVNStatusFrm.UpdateCheckedStatus;
var
i : Integer;
begin
for i := 0 to SVNFileListView.Items.Count - 1 do
with SVNFileListView.Items[i] do
SVNStatus.List[Index].Checked := Checked;
end;
procedure TSVNStatusFrm.FormCreate(Sender: TObject);
var
Config: TConfigStorage;
count: integer;
i: integer;
s: string;
begin
mnuShowDiff.Caption := rsShowDiff;
mnuOpen.Caption := rsOpenFileInEditor;
mnuRevert.Caption := rsRevert;
mnuAdd.Caption := rsAdd;
mnuRemove.Caption := rsRemove;
ButtonPanel.HelpButton.Caption:=rsCreatePatchFile;
ButtonPanel.OKButton.Caption:=rsCommit;
ButtonPanel.OKButton.OnClick:=@OKButtonClick;
SetColumn(SVNFileListView, 0, 25, '', False);
SetColumn(SVNFileListView, 1, 300, rsPath, False);
SetColumn(SVNFileListView, 2, 75, rsExtension, True);
SetColumn(SVNFileListView, 3, 100, rsFileStatus, True);
SetColumn(SVNFileListView, 4, 125, rsPropertyStatus, True);
SetColumn(SVNFileListView, 5, 75, rsRevision, True);
SetColumn(SVNFileListView, 6, 75, rsCommitRevision, True);
SetColumn(SVNFileListView, 7, 75, rsAuthor, True);
SetColumn(SVNFileListView, 8, 75, rsDate, True);
ImageList.AddResourceName(HInstance, 'menu_svn_diff');
ImageList.AddResourceName(HInstance, 'menu_svn_revert');
try
Config := GetIDEConfigStorage('lazsvnpkg.xml', true);
count := Config.GetValue('HistoryCount', 0);
//limit to 100 entries
if count > 100 then
count := 100;
for i := count downto 0 do
begin
s := Config.GetValue('Msg' + IntToStr(i), '');
if s <> '' then
SVNCommitMsgHistoryComboBox.Items.Add(s);
end;
finally
Config.Free;
end;
end;
procedure TSVNStatusFrm.FormDestroy(Sender: TObject);
begin
SVNStatusFrm := nil;
end;
procedure TSVNStatusFrm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var
Config: TConfigStorage;
count: integer;
begin
if SVNCommitMsgMemo.Text <> '' then
begin
try
Config := GetIDEConfigStorage('lazsvnpkg.xml', true);
count := Config.GetValue('HistoryCount', 0);
Config.SetValue('HistoryCount', count + 1);
Config.SetValue('Msg' + IntToStr(count + 1), SVNCommitMsgMemo.Text);
finally
Config.Free;
end;
end;
SVNStatus.Free;
CloseAction := caFree;
end;
procedure TSVNStatusFrm.CancelButtonClick(Sender: TObject);
begin
Close;
end;
end.