/components/lazsvnpkg/svnstatusform.pas
http://github.com/graemeg/lazarus · Pascal · 455 lines · 360 code · 52 blank · 43 comment · 29 complexity · fdb0323a75d6add33057d6ca5f6036cc MD5 · raw file
- { 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., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, 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 (LowerCase(StatusItem.ItemStatus) <> 'unversioned') and
- (LowerCase(StatusItem.ItemStatus) <> 'added') 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.