- [2012/12/07追記] masterのdefaultブランチにこの修正をマージしてもらいました。
やりたいこと
TortoiseHgで、ファイルのDiffやBlameを表示すると、変更箇所を表示するインジケータが一緒に表示されますよね?
ウインドウをスクロールするとそれにあわせて灰色の箱が動いたりするんですが、ここ、クリックしたくなりませんか?
クリックしたらその位置にジャンプしてくれるととてもうれしいんですが。僕は。
やったこと
という訳で少し手を入れてみました。
https://bitbucket.org/iwata0303/thg/commits/bbb613be1df57a43c4e3f6c20aa10ad45fe26c93
tortoisehg/hgqt/blockmatcher.pyというファイルがあって、そこにあるBlockListというクラスにこのメソッドを追加してます。
def scrollToPos(self, y):
# Scroll to the position which specified by Y coodinate.
if not isinstance(self._sbar, QScrollBar):
return
ratio = float(y) / self.height()
minimum, maximum, step = self._minimum, self._maximum, self._pagestep
value = minimum + (maximum + step - minimum) * ratio - (step * 0.5)
value = min(maximum, max(minimum, value)) # round to valid range.
self.setValue(value)
def mousePressEvent(self, event):
super(BlockList, self).mousePressEvent(event)
self.scrollToPos(event.y())
def mouseMoveEvent(self, event):
super(BlockList, self).mouseMoveEvent(event)
self.scrollToPos(event.y())
これで、インジケータ上をクリックすればその位置までジャンプしますし、そのまま上下にドラッグすればスクロールも連動するようになりました。
プラグインにしてみる
さて、とはいえ、これだけのためにTortoiseHgのソースを入手してビルドして、というのも面倒な話ですね。
ちょっと良い子にはお勧めできない系になりますが 、エクステンションを使ってモンキーパッチあててみます。
# -*- coding:utf-8 -*-
def extsetup():
import sys
import os
# thg.exeやthgw.exeから実行されたときだけ処理をするようにする
if not os.path.basename(sys.argv[0]).startswith('thg'):
return
from PyQt4.QtGui import QScrollBar
from tortoisehg.hgqt.blockmatcher import BlockList
from types import MethodType
mousePressEvent_org = BlockList.mousePressEvent
mouseMoveEvent_org = BlockList.mouseMoveEvent
def scrollToPos(bl, y):
# Scroll to the position which specified by Y coodinate.
if not isinstance(bl._sbar, QScrollBar):
return
ratio = float(y) / bl.height()
minimum, maximum, step = bl._minimum, bl._maximum, bl._pagestep
value = minimum + (maximum + step - minimum) * ratio - (step * 0.5)
value = min(maximum, max(minimum, value)) # round to valid range.
bl.setValue(value)
def mousePressEvent(self, event):
mousePressEvent_org(self, event)
scrollToPos(self, event.y())
def mouseMoveEvent(self, event):
mouseMoveEvent_org(self, event)
scrollToPos(self, event.y())
BlockList.mousePressEvent = MethodType(mousePressEvent, None, BlockList)
BlockList.mouseMoveEvent = MethodType(mouseMoveEvent, None, BlockList)
ふつうにhgコマンドを叩いた時に悪さされても困るので、thg*.exeとかから実行されたときだけ処理をするようにしています。
確認してませんがLinuxとかだと sys.arg[0]
はpythonのパスが入ってくると思うので、その場合は sys.arg[1]
でチェックする感じで。
このファイルを適当にエクステンションとして登録すれば、本体のソースに手を入れなくてもいけるようになります。
あくまでモンキーパッチなので、バージョンアップなどの際にはご注意を。