425 lines
15 KiB
ObjectPascal
425 lines
15 KiB
ObjectPascal
{**************************************************************************************************}
|
|
{ }
|
|
{ Project JEDI Code Library (JCL) }
|
|
{ }
|
|
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
|
|
{ you may not use this file except in compliance with the License. You may obtain a copy of the }
|
|
{ License at http://www.mozilla.org/MPL/ }
|
|
{ }
|
|
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF }
|
|
{ ANY KIND, either express or implied. See the License for the specific language governing rights }
|
|
{ and limitations under the License. }
|
|
{ }
|
|
{ The Original Code is JclVersionCtrlSVNImpl.pas }
|
|
{ }
|
|
{ The Initial Developer of the Original Code is Florent Ouchet. }
|
|
{ Portions created by Florent Ouchet are Copyright (C) of Florent Ouchet. }
|
|
{ Portions created by Elahn Ientile are Copyright (C) of Elahn Ientile. }
|
|
{ }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
{ }
|
|
{ Unit owner: Florent Ouchet }
|
|
{ Last modified: $Date: 2006/01/26 06:15:17 $ }
|
|
{ Revision: $Revision: 1.3 $ }
|
|
{ }
|
|
{**************************************************************************************************}
|
|
|
|
unit JclVersionCtrlSVNImpl;
|
|
|
|
{$I jcl.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
SysUtils, Classes, Windows, Graphics,
|
|
VersionControlImpl;
|
|
|
|
type
|
|
TJclVersionControlSVN = class (TJclVersionControlPlugin)
|
|
private
|
|
FTortoiseSVNProc: string;
|
|
protected
|
|
function GetSupportedActions: TJclVersionControlActions; override;
|
|
function GetFileActions(const FileName: string): TJclVersionControlActions; override;
|
|
function GetSandboxActions(const SdBxName: string): TJclVersionControlActions; override;
|
|
function GetIcon(const Action: TJclVersionControlAction): Integer; override;
|
|
function GetEnabled: Boolean; override;
|
|
function GetName: string; override;
|
|
public
|
|
constructor Create(const AExpert: TJclVersionControlExpert); override;
|
|
destructor Destroy; override;
|
|
function GetSandboxNames(const FileName: string; SdBxNames: TStrings): Boolean; override;
|
|
function ExecuteAction(const FileName: string;
|
|
const Action: TJclVersionControlAction): Boolean; override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
JclFileUtils, JclRegistry,
|
|
JclOtaUtils, JclOtaResources, JclOtaConsts;
|
|
|
|
const
|
|
JclVersionCtrlRegKeyName = 'SOFTWARE\TortoiseSVN';
|
|
JclVersionCtrlRegValueName = 'ProcPath';
|
|
JclVersionCtrlSVNAddVerb = 'add';
|
|
JclVersionCtrlSVNBlameVerb = 'blame';
|
|
JclVersionCtrlSVNBranchVerb = 'copy';
|
|
JclVersionCtrlSVNCheckOutVerb = 'checkout';
|
|
JclVersionCtrlSVNCommitVerb = 'commit';
|
|
JclVersionCtrlSVNDiffVerb = 'diff';
|
|
JclVersionCtrlSVNGraphVerb = 'revisiongraph';
|
|
JclVersionCtrlSVNLogVerb = 'log';
|
|
JclVersionCtrlSVNLockVerb = 'lock';
|
|
JclVersionCtrlSVNMergeVerb = 'merge';
|
|
JclVersionCtrlSVNRenameVerb = 'rename';
|
|
JclVersionCtrlSVNRepoBrowserVerb = 'repobrowser';
|
|
JclVersionCtrlSVNRevertVerb = 'revert';
|
|
JclVersionCtrlSVNStatusVerb = 'repostatus';
|
|
JclVersionCtrlSVNTagVerb = 'copy';
|
|
JclVersionCtrlSVNUpdateVerb = 'update';
|
|
JclVersionCtrlSVNUpdateToParam = '/rev';
|
|
JclVersionCtrlSVNUnlockVerb = 'unlock';
|
|
JclVersionCtrlSVNTortoiseDLL = 'TortoiseSVN.dll';
|
|
JclVersionCtrlSVNDirectory1 = '.svn\';
|
|
JclVersionCtrlSVNDirectory2 = '_svn\';
|
|
JclVersionCtrlSVNEntryFile = 'entries';
|
|
|
|
JclVersionCtrlSVNDirectories: array [0..1] of string =
|
|
( JclVersionCtrlSVNDirectory1, JclVersionCtrlSVNDirectory2 );
|
|
|
|
resourcestring
|
|
RsVersionCtrlSVNName = 'subversion';
|
|
RsEEmptyFileName = 'Error: empty file name';
|
|
RSENoTortoiseSVN = 'TortoiseSVN is not detected on the system';
|
|
|
|
//=== TJclVersionControlSVN ==================================================
|
|
|
|
constructor TJclVersionControlSVN.Create(const AExpert: TJclVersionControlExpert);
|
|
begin
|
|
inherited Create(AExpert);
|
|
FTortoiseSVNProc := RegReadStringDef(HKLM, JclVersionCtrlRegKeyName, JclVersionCtrlRegValueName, '');
|
|
end;
|
|
|
|
destructor TJclVersionControlSVN.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TJclVersionControlSVN.ExecuteAction(const FileName: string;
|
|
const Action: TJclVersionControlAction): Boolean;
|
|
function CallTortoiseSVNProc(const ActionName: string;
|
|
const Param: string = ''): Boolean;
|
|
var
|
|
StartupInfo: TStartupInfo;
|
|
ProcessInfo: TProcessInformation;
|
|
CurrentDir, CommandLine: string;
|
|
begin
|
|
FillChar(StartupInfo,SizeOf(TStartupInfo),#0);
|
|
FillChar(ProcessInfo,SizeOf(TProcessInformation),#0);
|
|
startupInfo.cb := SizeOf(TStartupInfo);
|
|
startupInfo.dwFlags := STARTF_USESHOWWINDOW;
|
|
startupInfo.wShowWindow := SW_SHOW;
|
|
|
|
if FileName = '' then
|
|
raise EJclExpertException.CreateTrace(RsEEmptyFileName);
|
|
if not Enabled then
|
|
raise EJClExpertException.CreateTrace(RsENoTortoiseSVN);
|
|
|
|
if FileName[Length(FileName)] = PathSeparator then
|
|
CurrentDir := FileName
|
|
else
|
|
CurrentDir := ExtractFilePath(FileName);
|
|
CommandLine := Format('%s /command:%s /path:"%s" %s /notempfile', [FTortoiseSVNProc, ActionName, FileName, Param]);
|
|
|
|
Result := CreateProcess(nil, PChar(CommandLine), nil,
|
|
nil, False, 0, nil, PChar(CurrentDir), StartupInfo, ProcessInfo);
|
|
|
|
if Result then
|
|
begin
|
|
CloseHandle(ProcessInfo.hProcess);
|
|
CloseHandle(ProcessInfo.hThread);
|
|
end;
|
|
end;
|
|
begin
|
|
case Action of
|
|
vcaAdd,
|
|
vcaAddSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNAddVerb);
|
|
vcaBlame :
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNBlameVerb);
|
|
vcaBranch,
|
|
vcaBranchSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNBranchVerb);
|
|
vcaCheckOutSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNCheckOutVerb);
|
|
vcaCommit,
|
|
vcaCommitSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNCommitVerb);
|
|
vcaDiff:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNDiffVerb);
|
|
vcaGraph:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNGraphVerb);
|
|
vcaLog,
|
|
vcaLogSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNLogVerb);
|
|
vcaLock,
|
|
vcaLockSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNLockVerb);
|
|
vcaMerge,
|
|
vcaMergeSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNMergeVerb);
|
|
vcaRename:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNRenameVerb);
|
|
vcaRepoBrowser:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNRepoBrowserVerb);
|
|
vcaRevert,
|
|
vcaRevertSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNRevertVerb);
|
|
vcaStatus,
|
|
vcaStatusSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNStatusVerb);
|
|
vcaTag,
|
|
vcaTagSandBox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNTagVerb);
|
|
vcaUpdate,
|
|
vcaUpdateSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNUpdateVerb);
|
|
vcaUpdateTo,
|
|
vcaUpdateSandboxTo:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNUpdateVerb, JclVersionCtrlSVNUpdateToParam);
|
|
vcaUnlock,
|
|
vcaUnlockSandbox:
|
|
Result := CallTortoiseSVNProc(JclVersionCtrlSVNUnlockVerb);
|
|
else
|
|
Result := inherited ExecuteAction(FileName, Action);
|
|
end;
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetEnabled: Boolean;
|
|
begin
|
|
Result := FTortoiseSVNProc <> '';
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetFileActions(
|
|
const FileName: string): TJclVersionControlActions;
|
|
var
|
|
EntryFile: string;
|
|
Entries: TStrings;
|
|
IndexDir, IndexEntry: Integer;
|
|
FileNameValue: string;
|
|
begin
|
|
Result := inherited GetFileActions(FileName);
|
|
|
|
if Enabled then
|
|
begin
|
|
Entries := TStringList.Create;
|
|
try
|
|
FileNameValue := Format('NAME="%s"', [ExtractFileName(AnsiUpperCaseFileName(FileName))]);
|
|
|
|
for IndexDir := Low(JclVersionCtrlSVNDirectories) to High(JclVersionCtrlSVNDirectories) do
|
|
begin
|
|
EntryFile := PathAddSeparator(ExtractFilePath(FileName))
|
|
+ JclVersionCtrlSVNDirectories[IndexDir] + JclVersionCtrlSVNEntryFile;
|
|
|
|
if FileExists(EntryFile) then
|
|
begin
|
|
Entries.LoadFromFile(EntryFile);
|
|
|
|
for IndexEntry := 0 to Entries.Count - 1 do
|
|
if Pos(FileNameValue, AnsiUpperCase(Entries.Strings[IndexEntry])) > 0 then
|
|
begin
|
|
// TODO: check modifications
|
|
Result := Result + [vcaBlame, vcaBranch, vcaCommit, vcaDiff, vcaGraph,
|
|
vcaLog, vcaLock, vcaMerge, vcaRename, vcaRevert, vcaRepoBrowser,
|
|
vcaStatus, vcaTag, vcaUpdate, vcaUpdateTo, vcaUnlock];
|
|
FreeAndNil(Entries);
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
finally
|
|
Entries.Free;
|
|
end;
|
|
Result := Result + [vcaAdd];
|
|
end;
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetSupportedActions: TJclVersionControlActions;
|
|
begin
|
|
Result := inherited GetSupportedActions;
|
|
if Enabled then
|
|
Result := Result + [vcaAdd, vcaAddSandbox, vcaBlame, vcaBranch,
|
|
vcaBranchSandbox, vcaCheckOutSandbox, vcaCommit, vcaCommitSandbox, vcaDiff,
|
|
vcaGraph, vcaLog, vcaLogSandbox, vcaLock, vcaLockSandbox, vcaMerge,
|
|
vcaMergeSandbox, vcaRename, vcaRepoBrowser, vcaRevert, vcaRevertSandbox,
|
|
vcaStatus, vcaStatusSandbox, vcaTag, vcaTagSandBox, vcaUpdate,
|
|
vcaUpdateSandbox, vcaUpdateTo, vcaUpdateSandboxTo, vcaUnlock, vcaUnlockSandbox];
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetIcon(
|
|
const Action: TJclVersionControlAction): Integer;
|
|
var
|
|
LibraryName: string;
|
|
begin
|
|
LibraryName := PathAddSeparator(ExtractFilePath(FTortoiseSVNProc)) + JclVersionCtrlSVNTortoiseDLL;
|
|
|
|
case Action of
|
|
vcaAdd,
|
|
vcaAddSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 124);
|
|
vcaBlame:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 5146);
|
|
vcaBranch,
|
|
vcaBranchSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 132);
|
|
vcaCheckOutSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 121);
|
|
vcaCommit,
|
|
vcaCommitSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 123);
|
|
vcaDiff:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 135);
|
|
vcaGraph:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 5151);
|
|
vcaLog,
|
|
vcaLogSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 136);
|
|
vcaLock,
|
|
vcaLockSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 5152);
|
|
vcaMerge,
|
|
vcaMergeSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 129);
|
|
vcaRename:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 134);
|
|
vcaRepoBrowser:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 5145);
|
|
vcaRevert,
|
|
vcaRevertSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 125);
|
|
vcaStatus,
|
|
vcaStatusSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 143);
|
|
vcaTag,
|
|
vcaTagSandBox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 132);
|
|
vcaUpdate,
|
|
vcaUpdateSandbox,
|
|
vcaUpdateTo,
|
|
vcaUpdateSandboxTo:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 122);
|
|
vcaUnlock,
|
|
vcaUnlockSandbox:
|
|
Result := Expert.CacheResourceIcon(LibraryName, 5153);
|
|
else
|
|
Result := inherited GetIcon(Action);
|
|
end;
|
|
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetName: string;
|
|
begin
|
|
Result := RsVersionCtrlSVNName;
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetSandboxActions(
|
|
const SdBxName: string): TJclVersionControlActions;
|
|
var
|
|
SvnDirectory: string;
|
|
IndexDir: Integer;
|
|
begin
|
|
Result := inherited GetSandboxActions(SdBxName);
|
|
|
|
if Enabled then
|
|
begin
|
|
for IndexDir := Low(JclVersionCtrlSVNDirectories) to High(JclVersionCtrlSVNDirectories) do
|
|
begin
|
|
SvnDirectory := sdBxName + JclVersionCtrlSVNDirectories[IndexDir];
|
|
|
|
if DirectoryExists(SvnDirectory) then
|
|
begin
|
|
Result := Result + [vcaAddSandbox, vcaBranchSandbox, vcaCommitSandbox,
|
|
vcaLogSandbox, vcaLockSandbox, vcaMergeSandbox, vcaRevertSandbox,
|
|
vcaStatusSandbox, vcaTagSandBox, vcaUpdateSandbox, vcaUpdateSandboxTo,
|
|
vcaUnlockSandbox];
|
|
Exit;
|
|
end;
|
|
end;
|
|
// not in a sandbox
|
|
Result := Result + [vcaCheckOutSandbox];
|
|
end;
|
|
end;
|
|
|
|
function TJclVersionControlSVN.GetSandboxNames(const FileName: string;
|
|
SdBxNames: TStrings): Boolean;
|
|
var
|
|
DirectoryName: string;
|
|
IndexDir, IndexFileName: Integer;
|
|
begin
|
|
Result := True;
|
|
|
|
SdBxNames.BeginUpdate;
|
|
try
|
|
SdBxNames.Clear;
|
|
|
|
if Enabled then
|
|
for IndexFileName := Length(FileName) downto 1 do
|
|
if FileName[IndexFileName] = PathSeparator then
|
|
begin
|
|
for IndexDir := Low(JclVersionCtrlSVNDirectories) to High(JclVersionCtrlSVNDirectories) do
|
|
begin
|
|
DirectoryName := Copy(FileName, 1, IndexFileName) + JclVersionCtrlSVNDirectories[IndexDir];
|
|
if DirectoryExists(DirectoryName) then
|
|
SdBxNames.Add(DirectoryName);
|
|
end;
|
|
end;
|
|
finally
|
|
SdBxNames.EndUpdate;
|
|
end;
|
|
|
|
if SdBxNames.Count = 0 then
|
|
Result := inherited GetSandboxNames(FileName, SdBxNames);
|
|
end;
|
|
|
|
initialization
|
|
|
|
try
|
|
TJclVersionControlExpert.RegisterPluginClass(TJclVersionControlSVN);
|
|
except
|
|
on ExceptionObj: TObject do
|
|
begin
|
|
JclExpertShowExceptionDialog(ExceptionObj);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
finalization
|
|
|
|
try
|
|
TJclVersionControlExpert.UnregisterPluginClass(TJclVersionControlSVN);
|
|
except
|
|
on ExceptionObj: TObject do
|
|
begin
|
|
JclExpertShowExceptionDialog(ExceptionObj);
|
|
raise;
|
|
end;
|
|
end;
|
|
|
|
// History:
|
|
|
|
// $Log: JclVersionCtrlSVNImpl.pas,v $
|
|
// Revision 1.3 2006/01/26 06:15:17 outchy
|
|
// Repository browser now works
|
|
//
|
|
// Revision 1.2 2006/01/25 20:33:27 outchy
|
|
// Added _svn as a valid subdirectory
|
|
//
|
|
// Revision 1.1 2006/01/15 00:51:22 outchy
|
|
// cvs support in version control expert
|
|
// version control expert integration in the installer
|
|
//
|
|
|
|
end.
|