I'd like to automatically checkout a file when I start to edit it in Delphi 7 IDE.
ClearCase is my version control system and I really hate the need to checkout a file before starting to edit. It always breaks my thought flow: I'm trying to solve a problem, find where I need to change, try to edit it, fail because the file is read only, open clearcase, search the file, finally checkout, try to edit the file again, fail because the IDE still thinks it is readonly, tell the IDE that isn't readonly. When I finally go back to code, I forgot what I was trying do do.
I've found this nice and simple ClearCase IDE integration code. It works, but uses the deprecated ToolIntf unit. I've added a couple of shortcuts. Here is a simplified version of it (didn't try to compile):
unit clearcase;
interface
uses ToolsApi, ToolIntf;
implementation
uses
Windows, Dialogs, Classes, ExptIntf, Menus, ShellApi, SysUtils;
type
TDelphiClearcase = class
private
FClearcaseMenu,
FDoCheckOutPasDfm,
FDoCheckInPasDfm : TIMenuItemIntf;
procedure ExecCommand(const command: string; path: PChar = nil);
public
destructor Destroy;override;
procedure DoClick(Sender: TIMenuItemIntf);
property ClearcaseMenu: TIMenuItemIntf read FClearcaseMenu write FClearcaseMenu;
property DoCheckOutPasDfm:TIMenuItemIntf write FDoCheckOutPasDfm;
property DoCheckInPasDfm: TIMenuItemIntf write FDoCheckInPasDfm;
end;
var
dcc: TDelphiClearcase = nil;
{ TDelphiClearcase }
destructor TDelphiClearcase.Destroy;
procedure Remove(item: TIMenuItemIntf);
begin
if( item = nil )then
Exit;
item.DestroyMenuItem;
FreeAndNil(item);
end;
begin
Remove(FDoCheckOutPasDfm);
Remove(FDoCheckInPasDfm);
inherited;
end;
procedure TDelphiClearcase.DoClick(Sender: TIMenuItemIntf);
function GetPasDfm(const f: string): string;
var
aux: string;
begin
aux := Copy(f, 1, Length(f) - 4);
Result := aux + '.pas' + ' ' + aux + '.dfm'
end;
var
command, fileName : string;
begin
fileName := ToolServices.GetCurrentFile;
if( Sender = FDoCheckOutPasDfm )then
command := 'cleartool co ' + GetPasDfm(fileName)
else if( Sender = FDoCheckInPasDfm )then
command := 'cleartool ci ' + GetPasDfm(fileName);
ExecCommand(command);
ToolServices.ReloadFile(fileName);
end;
procedure TDelphiClearcase.ExecCommand(const command: string; path: PChar);
var
pi : TProcessInformation;
stinfo : TStartupInfo;
begin
FillChar(stinfo, SizeOf(stinfo), 0);
stinfo.cb := SizeOf(stinfo);
if( CreateProcess(nil, PChar(command), nil, nil, True, CREATE_NEW_CONSOLE,
nil, path, stinfo, pi) )then begin
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess)
end
end;
procedure CreateMenus;
var
services: TIToolServices;
begin
if( BorlandIDEServices = nil )then
Exit;
services := ToolServices;
if( services = nil )then
Exit;
dcc := TDelphiClearcase.Create;
dcc.ClearcaseMenu := services.GetMainMenu.GetMenuItems.InsertItem(6,
'C&learcase', 'ClearcaseMenu', 'ClearcaseTools', 0, 0, 0,
[mfEnabled, mfVisible], nil);
dcc.DoCheckOutPasDfm := dcc.ClearcaseMenu.InsertItem(2,
'Check Out pas and dfm', 'DoCheckOutPasDfm', 'Undo the check outs', ShortCut(Ord('>'),
[ssCtrl]), 0, 2,
[mfEnabled, mfVisible], dcc.DoClick);
dcc.DoCheckInPasDfm:= dcc.ClearcaseMenu.InsertItem(4,
'Check In pas and dfm', 'DoCheckInPasDfm', 'Check in current files', ShortCut(Ord('<'),
[ssCtrl]), 0, 2,
[mfEnabled, mfVisible], dcc.DoClick);
end;
procedure DestroyMenus;
begin
FreeAndNil(dcc);
end;
initialization
CreateMenus;
finalization
DestroyMenus
end.
I'd like to checkout the file when I first start editing it and it is read only. I have no idea how to hook a function to the IDE edit event of a file. Any pointers are welcome.