unit TortoiseSVN2IDE;

{$R 'icons.res'}

interface

uses ToolsAPI, SysUtils, Windows, Dialogs, Menus, Registry, ShellApi,
    Classes, Controls, Graphics, ImgList, ExtCtrls, ActnList,Forms;//增加了对Forms单元的引用

const
    SVN_PROJECT_EXPLORER = 0;
    SVN_LOG = 1;
    SVN_CHECK_MODIFICATIONS = 2;
    SVN_ADD = 3;
    SVN_UPDATE = 4;
    SVN_COMMIT = 5;
    SVN_DIFF = 6;
    SVN_REVERT = 7;
    SVN_REPOSITORY_BROWSER = 8;
    SVN_SETTINGS = 9;
    SVN_ABOUT = 10;
    SVN_VERB_COUNT = 11;

type TTortoiseSVN = class(TNotifierObject, IOTANotifier, IOTAWizard)
private
    timer: TTimer;
    tsvnMenu: TMenuItem;
    TSVNPath: string;
    procedure Tick( sender: tobject );
    procedure TSVNExec( params: string );
    function GetBitmapName(Index: Integer): string;
    function GetVerb(Index: Integer): string;
    function GetVerbState(Index: Integer): Word;
    procedure ExecuteVerb(Index: Integer);
    procedure CreateMenu;
    procedure UpdateAction( sender: TObject );
    procedure ExecuteAction( sender: TObject );
public
    constructor Create;
    destructor Destroy; override;
    function GetIDString: string;
    function GetName: string;
    function GetState: TWizardState;
    procedure Execute;
end;

{$IFNDEF DLL_MODE}

procedure Register;

{$ELSE}

function InitWizard(const BorlandIDEServices: IBorlandIDEServices;
  RegisterProc: TWizardRegisterProc;
  var Terminate: TWizardTerminateProc): Boolean; stdcall;

{$ENDIF}

implementation

function GetCurrentProject: IOTAProject;
var
  ModServices: IOTAModuleServices;
  Module: IOTAModule;
  Project: IOTAProject;
  ProjectGroup: IOTAProjectGroup;
  i: Integer;
begin
  Result := nil;
  ModServices := BorlandIDEServices as IOTAModuleServices;
  if ModServices <> nil then
      for i := 0 to ModServices.ModuleCount - 1 do
      begin
        Module := ModServices.Modules[i];
        if Supports(Module, IOTAProjectGroup, ProjectGroup) then
        begin
          Result := ProjectGroup.ActiveProject;
          Exit;
        end
        else if Supports(Module, IOTAProject, Project) then
        begin // In the case of unbound packages, return the 1st
          if Result = nil then
            Result := Project;
        end;
      end;
end;

function GetCurrentFileName: string;
var editor: IOTAEditorServices;
begin
    result:= '';
    editor:= BorlandIDEServices as IOTAEditorServices;
    if editor <> nil then begin
        if editor.TopBuffer <> nil then
            result:= editor.TopBuffer.FileName;
    end;
end;

constructor TTortoiseSVN.Create;
var reg: TRegistry;
begin
    Reg := TRegistry.Create;
    try
        Reg.RootKey := HKEY_LOCAL_MACHINE;
        if Reg.OpenKeyReadOnly( '\SOFTWARE\TortoiseSVN' ) then
            TSVNPath:= Reg.ReadString( 'ProcPath' );
    finally
        Reg.CloseKey;
        Reg.Free;
    end;

tsvnMenu:= nil;

timer:= TTimer.create(nil);
    timer.interval:= 200;
    timer.OnTimer:= tick;
    timer.enabled:= true;

end;

procedure TTortoiseSVN.Tick( sender: tobject );
var intf: INTAServices;
begin
    if BorlandIDEServices.QueryInterface( INTAServices, intf ) = s_OK then begin
        self.createMenu;
        timer.free;
        timer:= nil;
    end;
end;

procedure TTortoiseSVN.CreateMenu;
var mainMenu: TMainMenu;
    item: TMenuItem;
    i: integer;
    bmp: TBitmap;
    action: TAction;
begin
    if tsvnMenu <> nil then exit;

tsvnMenu:= TMenuItem.Create(nil);
    tsvnMenu.Caption:= 'TortoiseSVN';

for i:= 0 to SVN_VERB_COUNT-1 do begin

bmp:= TBitmap.create;
        try
          bmp.LoadFromResourceName( HInstance, getBitmapName(i) );
        except end;

action:= TAction.Create(nil);
        action.ActionList:= (BorlandIDEServices as INTAServices).ActionList;
        action.Caption:= getVerb(i);
        action.Hint:= getVerb(i);
        if (bmp.Width = 16) and (bmp.height = 16) then
            action.ImageIndex:= (BorlandIDEServices as INTAServices).AddMasked( bmp, clBlack );
        bmp.free;
        action.OnUpdate:= updateAction;
        action.OnExecute:= executeAction;
        action.Tag:= i;

item:= TMenuItem.Create( tsvnMenu );
        item.action:= action;

tsvnMenu.add( item );
    end;

mainMenu:= (BorlandIDEServices as INTAServices).MainMenu;
    mainMenu.Items.Insert( mainMenu.Items.Count-1, tsvnMenu );
end;

destructor TTortoiseSVN.Destroy;
begin
    if tsvnMenu <> nil then begin
        tsvnMenu.free;
    end;
    inherited;
end;

function TTortoiseSVN.GetBitmapName(Index: Integer): string;
begin
    case index of
        SVN_PROJECT_EXPLORER:
            Result:= 'explorer';
        SVN_LOG:
            Result:= 'log';
        SVN_CHECK_MODIFICATIONS:
            Result:= 'check';
        SVN_ADD:
            Result:= 'add';
        SVN_UPDATE:
            Result:= 'update';
        SVN_COMMIT:
            Result:= 'commit';
        SVN_DIFF:
            Result:= 'diff';
        SVN_REVERT:
            Result:= 'revert';
        SVN_REPOSITORY_BROWSER:
            Result:= 'repository';
        SVN_SETTINGS:
            Result:= 'settings';
        SVN_ABOUT:
            Result:= 'about';
    end;
end;

function TTortoiseSVN.GetVerb(Index: Integer): string;
begin
    case index of
        SVN_PROJECT_EXPLORER:
            Result:= '浏览项目文件夹[&P]...';//'&Project explorer...';
        SVN_LOG:
            Result:= '日志[&L]...';//'&Log...';
        SVN_CHECK_MODIFICATIONS:
            Result:= '检查更新[&M]...';//'Check &modifications...';
        SVN_ADD:
            Result:= '添加[&A]...';//'&Add...';
        SVN_UPDATE:
            Result:= '更新为某一版本[&U]...';//'&Update to revision...';
        SVN_COMMIT:
            Result:= '提交[&C]...';//'&Commit...';
        SVN_DIFF:
            Result:= '差异比较[&D]...';//'&Diff...';
        SVN_REVERT:
            Result:= '还原[&R]...';//'&Revert...';
        SVN_REPOSITORY_BROWSER:
            Result:= '浏览版本库[&B]...';//'Repository &browser...';
        SVN_SETTINGS:
            Result:= '设置[&S]...';//'&Settings...';
        SVN_ABOUT:
            Result:= '关于[&A]...';//'&About...';
    end;
end;

const vsEnabled = 1;

function TTortoiseSVN.GetVerbState(Index: Integer): Word;
begin
    Result:= 0;
    case index of
        SVN_PROJECT_EXPLORER:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_LOG:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_CHECK_MODIFICATIONS:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_ADD:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_UPDATE:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_COMMIT:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_DIFF:
            if GetCurrentFileName <> '' then
                Result:= vsEnabled;
        SVN_REVERT:
            if GetCurrentProject <> nil then
                Result:= vsEnabled;
        SVN_REPOSITORY_BROWSER:
            Result:= vsEnabled;
        SVN_SETTINGS:
            Result:= vsEnabled;
        SVN_ABOUT:
            Result:= vsEnabled;
    end;
end;

procedure TTortoiseSVN.TSVNExec( params: string );
begin
    WinExec( pchar( TSVNPath + ' ' + params ), SW_SHOW );
end;

procedure TTortoiseSVN.ExecuteVerb(Index: Integer);
var project: IOTAProject;
    filename: string;
begin
    project:= GetCurrentProject();
    filename:= getCurrentFileName();
    case index of
        SVN_PROJECT_EXPLORER:
            if project <> nil then
                ShellExecute( 0, 'open', pchar( ExtractFilePath(project.GetFileName) ), '', '', SW_SHOWNORMAL );
        SVN_LOG:
            if project <> nil then
                TSVNExec( '/command:log /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) );
        SVN_CHECK_MODIFICATIONS:
            if project <> nil then
                TSVNExec( '/command:repostatus /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) );
        SVN_ADD:
            if project <> nil then
                TSVNExec( '/command:add /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) );
        SVN_UPDATE:
            if project <> nil then

if Application.MessageBox('更新之前,所有的项目文件都将被保存。继续吗?  ', '提示',MB_YESNO + MB_ICONQUESTION) = IDYES then begin
                //if MessageDlg( '更新之前,所有的项目文件都将被保存。继续吗?', mtConfirmation, [mbYes, mbNo], 0 ) = mrYes then begin
                    (BorlandIDEServices as IOTAModuleServices).saveAll;
                    TSVNExec( '/command:update /rev /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) );
                end;
        SVN_COMMIT:
            if project <> nil then
                if Application.MessageBox('提交之前,所有的项目文件都将被保存。继续吗?  ', '提示',MB_YESNO + MB_ICONQUESTION) = IDYES then begin
                //if MessageDlg( '提交之前,所有的项目文件都将被保存。继续吗?', mtConfirmation, [mbYes, mbNo], 0 ) = mrYes then begin
                    (BorlandIDEServices as IOTAModuleServices).saveAll;
                    TSVNExec( '/command:commit /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) );
                end;
        SVN_DIFF:
            if filename <> '' then
                TSVNExec( '/command:diff /notempfile /path:' + AnsiQuotedStr( filename, '"' ) );
        SVN_REVERT:
            if project <> nil then
                TSVNExec( '/command:revert /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) );
        SVN_REPOSITORY_BROWSER:
            if project <> nil then
                TSVNExec( '/command:repobrowser /notempfile /path:' + AnsiQuotedStr( ExtractFilePath(project.GetFileName), '"' ) )
            else
                TSVNExec( '/command:repobrowser' );
        SVN_SETTINGS:
            TSVNExec( '/command:settings' );
        SVN_ABOUT:
            TSVNExec( '/command:about' );
    end;
end;

procedure TTortoiseSVN.UpdateAction( sender: TObject );
var action: TAction;
begin
    action:= sender as TAction;
    action.Enabled:= getVerbState( action.tag ) = vsEnabled;
end;

procedure TTortoiseSVN.ExecuteAction( sender: TObject );
var action: TAction;
begin
    action:= sender as TAction;
    executeVerb( action.tag );
end;

function TTortoiseSVN.GetIDString: string;
begin
    result:= 'Subversion.TortoiseSVN';
end;

function TTortoiseSVN.GetName: string;
begin
    result:= 'TortoiseSVN add-in';
end;

function TTortoiseSVN.GetState: TWizardState;
begin
    result:= [wsEnabled];
end;

procedure TTortoiseSVN.Execute;
begin
end;

{$IFNDEF DLL_MODE}

procedure Register;
begin
    RegisterPackageWizard(TTortoiseSVN.create);
end;

{$ELSE}

var wizardID: integer;

procedure FinalizeWizard;
var
  WizardServices: IOTAWizardServices;
begin
    Assert(Assigned(BorlandIDEServices));

WizardServices := BorlandIDEServices as IOTAWizardServices;
    Assert(Assigned(WizardServices));

WizardServices.RemoveWizard( wizardID );

end;

function InitWizard(const BorlandIDEServices: IBorlandIDEServices;
  RegisterProc: TWizardRegisterProc;
  var Terminate: TWizardTerminateProc): Boolean; stdcall;
var
  WizardServices: IOTAWizardServices;
begin
    Assert(BorlandIDEServices <> nil);
    Assert(ToolsAPI.BorlandIDEServices = BorlandIDEServices);

Terminate := FinalizeWizard;

WizardServices := BorlandIDEServices as IOTAWizardServices;
    Assert(Assigned(WizardServices));

wizardID:= WizardServices.AddWizard(TTortoiseSVN.Create as IOTAWizard);

result:= wizardID >= 0;
end;

exports
  InitWizard name WizardEntryPoint;

{$ENDIF}

end.

转载于:https://www.cnblogs.com/MaxWoods/archive/2010/04/09/1708673.html

TortoiseSVN2IDE.pas源代码相关推荐

  1. Delphi让你发送Flash电子邮件

    无论Outlook XP还是最新的Foxmail 4.0,都只能在HTML格式的电子邮件中嵌入JPG.GIF格式图片,而音色俱佳的Flash动画却只能作为电子邮件附件发送给好友,你可曾感到遗憾? 经过 ...

  2. c 语言切换源码,C转换为pas - 源码下载|其它|编译器/词法分析|源代码 - 源码中国...

    压缩包 : openc2pas-0_03_1.zip 列表 release/bin/ release/bin/OpenC2Pas.exe release/src/ release/src/main_m ...

  3. delphi技术专题---获取网卡物理地址之NB30.pas单元TNCB详解以及源代码分享

    接下来将要进入Netbios的编程应用阶段.要想调用Netbios API函数,需要链接系统的NETAPI32.DLL文件.Delphi提供了一个NB30单元Netbios API函数及相关的结构.常 ...

  4. delphi里的 .pas .dcu .dpk .dpl .res .cfg......分别是什么文件

    扩展名 英文解释 文件内容HWez BPG Borland Project Group 工程项目包, 多个工程文件DPR的集合ja DPR Delphi Project 应用系统的工程文件&- ...

  5. 浏览DELPHI的源代码

    浏览DELPHI的源代码 走马观花,浏览一下DELPHI的源代码是值得的.因为,DELPHI的源代码中蕴藏着丰富的营养,那都是大师们的杰作.如果,我们开发的应用应用程序是 一棵开花的树,那么,请在我们 ...

  6. delphi mysql.pas_mysql_pas DELPHI的 连接类源码,附带例程,无需ODBC驱动! VCL 269万源代码下载- www.pudn.com...

    文件名称: mysql_pas下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Delphi 文件大小: 1482 KB 上传时间: 2015-08-10 下载次数: 16 提 供 者 ...

  7. yt88加密狗不识别_YT88 是天域一个很不错的加密狗工具,可以源码 ,还 外壳 ,带DLK开发包。 Windows Develop 256万源代码下载- www.pudn.com...

    文件名称: YT88下载  收藏√  [ 5  4  3  2  1 ] 开发工具: Windows_Unix 文件大小: 12909 KB 上传时间: 2016-05-01 下载次数: 0 提 供 ...

  8. Linux开发之Delphi FMXLinux(二)、Delphi对Linux操作系统内核态主要的Api封装(FMUX.Api.pas)

    目录 Linux开发之Delphi FMXLinux(二).Delphi对Linux操作系统内核态主要的Api封装(FMUX.Api.pas) 1.代码的版权(比较新的代码库): 2.依赖: 3.其中 ...

  9. 主讲:A1(老吴) 时间:2004-10-22 15:00 主题:0一点点编译。1解决DLL与EXE沟通时String和其它Memory的问题.2公布hmOlevariants.pas 3成批...

    主讲:A1(老吴) 时间:2004-10-22 15:00 主题: 0>一点点编译. 1>解决DLL与EXE沟通时String和其它Memory的问题. 2>公布hmOlevaria ...

最新文章

  1. 这是什么神仙公司?居然公布离职员工信息,还给差评?
  2. (转载)计算机视觉、图像处理中常见的滤波操作
  3. php-cli下载,php-cli-color
  4. java接口作用和好处,持续更新大厂面试笔试题
  5. 一个适用各类场合的Makefile模板
  6. 168输出为861java_AcWing 861. 二分图的最大匹配-java-关键处注释
  7. Ubuntu安装特定版本安装包
  8. Excel转html
  9. 网络相关的常用协议总结
  10. 拼音转换成汉字html,汉字转换成拼音的种(转)
  11. 联众打码写滑动_自己写了一个答题的软件现在分享一下(在分享一下联众打码源码调用) _ 综合讨论 - 按键精灵论坛...
  12. 音乐盒单片机c语言课程设计,基于PIC16F887单片机数字音乐盒课程设计.doc
  13. 家庭网络布线工程图布线方案
  14. 获取GooglePlay下载来源广告数据统计接入
  15. 华为牛人的十年工作感悟
  16. 计算机视觉论文-2021-03-31
  17. 插件化开发之发展历史及特性区别总结
  18. 情人辞职信 [搞笑,也来个好玩的乐一乐]
  19. 使用 FFmpeg(bilibili视频m4s合成mp4)
  20. 【快速打点综合工具 -- ALLiN】

热门文章

  1. 在浏览器控制台输出内容 console.log(string);
  2. MAC OS X 10.9.X下用命令行开启SSD trim的方法汇总
  3. [html] 当html中使用map标签时,area中coords值如何精确定位呢?
  4. [css] 相邻兄弟选择器、后代选择器和子选择器三者有什么区别?
  5. [css] 说下你对css样式的这几个属性值initial、inherit、unset、revert的理解
  6. [css] 请使用css3实现图片的平滑转换
  7. 工作296:el-table使用
  8. 1前端学习(2345):关于前端对于xml格式文件的渲染
  9. 前端学习(1646):前端系列实战课程之右下角悬浮功能实现思路
  10. oracle之数据处理之约束1