[PATCH 1 of 6] filedialogs: look up last changed revision by goto(rev)

8 views
Skip to first unread message

Yuya Nishihara

unread,
Jun 1, 2013, 8:05:42 AM6/1/13
to thg...@googlegroups.com
# HG changeset patch
# User Yuya Nishihara <yu...@tcha.org>
# Date 1370085641 -32400
# Sat Jun 01 20:20:41 2013 +0900
# Node ID a2ea48e9aafc6e74672167ca72354d2fe57bb733
# Parent 945867029941bf5fba68c21dd4e73e1244d65382
filedialogs: look up last changed revision by goto(rev)

With this change, ManifestWidget can select the appropriate revision of
unchanged files at that revision.

indexLinkedFromRev() does not follow renames because it isn't necessary
for now. ManifestWidget opens FileLogDialog per filename.

diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -200,7 +200,7 @@ class FileLogDialog(_AbstractFileDialog)
def modelFilled(self):
self.repoview.resizeColumns()
if self._show_rev is not None:
- index = self.filerevmodel.indexFromRev(self._show_rev)
+ index = self.filerevmodel.indexLinkedFromRev(self._show_rev)
self._show_rev = None
elif self.repoview.currentIndex().isValid():
return # already set by goto()
@@ -396,7 +396,7 @@ class FileLogDialog(_AbstractFileDialog)
self.textView.showMessage.emit(msg)

def goto(self, rev):
- index = self.filerevmodel.indexFromRev(rev)
+ index = self.filerevmodel.indexLinkedFromRev(rev)
if index is not None:
self.repoview.setCurrentIndex(index)
else:
@@ -623,7 +623,7 @@ class FileDiffDialog(_AbstractFileDialog
self.update_diff(keeppos=otherside[side])

def goto(self, rev):
- index = self.filerevmodel.indexFromRev(rev)
+ index = self.filerevmodel.indexLinkedFromRev(rev)
if index is not None:
if index.row() == 0:
index = self.filerevmodel.index(1, 0)
diff --git a/tortoisehg/hgqt/filerevmodel.py b/tortoisehg/hgqt/filerevmodel.py
--- a/tortoisehg/hgqt/filerevmodel.py
+++ b/tortoisehg/hgqt/filerevmodel.py
@@ -14,6 +14,8 @@
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

+from mercurial import error
+
from tortoisehg.hgqt.repomodel import HgRepoListModel, COLUMNHEADERS
from tortoisehg.hgqt.graph import Graph, filelog_grapher
from tortoisehg.hgqt.i18n import _
@@ -74,3 +76,14 @@ class FileRevModel(HgRepoListModel):
else:
self.graph = None
self.heads = []
+
+ def indexLinkedFromRev(self, rev):
+ """Index for the last changed revision before the specified revision
+
+ This does not follow renames.
+ """
+ try:
+ fctx = self.repo[rev][self.filename]
+ except error.LookupError:
+ return None
+ return self.indexFromRev(fctx.linkrev())

Yuya Nishihara

unread,
Jun 1, 2013, 8:05:43 AM6/1/13
to thg...@googlegroups.com
# HG changeset patch
# User Yuya Nishihara <yu...@tcha.org>
# Date 1369567810 -32400
# Sun May 26 20:30:10 2013 +0900
# Node ID c7ed928b0021d2ba1f103f0c8f9390a675e31f1e
# Parent a2ea48e9aafc6e74672167ca72354d2fe57bb733
filedialogs: add forwarding methods necessary to act as annotate dialog

Based on ManifestDialog.

diff --git a/tortoisehg/hgqt/filedialogs.py b/tortoisehg/hgqt/filedialogs.py
--- a/tortoisehg/hgqt/filedialogs.py
+++ b/tortoisehg/hgqt/filedialogs.py
@@ -402,6 +402,18 @@ class FileLogDialog(_AbstractFileDialog)
else:
self._show_rev = rev

+ def showLine(self, line):
+ self.textView.showLine(line - 1) # fileview should do -1 instead?
+
+ def setFileViewMode(self, mode):
+ self.textView.setMode(mode)
+
+ def setSearchPattern(self, text):
+ self.textView.searchbar.setPattern(text)
+
+ def setSearchCaseInsensitive(self, ignorecase):
+ self.textView.searchbar.setCaseInsensitive(ignorecase)
+
def reload(self):
self.repoview.saveSettings()
super(FileLogDialog, self).reload()

Yuya Nishihara

unread,
Jun 1, 2013, 8:05:44 AM6/1/13
to thg...@googlegroups.com
# HG changeset patch
# User Yuya Nishihara <yu...@tcha.org>
# Date 1370086486 -32400
# Sat Jun 01 20:34:46 2013 +0900
# Node ID db9904c86e2fe52e5c259b179e6e0b76ab37b4ad
# Parent c7ed928b0021d2ba1f103f0c8f9390a675e31f1e
annotate: use FileLogDialog instead of ManifestDialog

Since annotate is file oriented, FileLogDialog is more suitable than
ManifestDialog. You can still open ManifestDialog by "thg manifest".

diff --git a/tortoisehg/hgqt/run.py b/tortoisehg/hgqt/run.py
--- a/tortoisehg/hgqt/run.py
+++ b/tortoisehg/hgqt/run.py
@@ -650,13 +650,31 @@ def add(ui, *pats, **opts):
_('thg annotate'))
def annotate(ui, *pats, **opts):
"""annotate dialog"""
- from tortoisehg.hgqt.manifestdialog import run
+ from tortoisehg.hgqt import filedialogs, fileview, thgrepo
if len(pats) != 1:
ui.warn(_('annotate requires a single filename\n'))
if pats:
pats = pats[0:]
else:
return
+
+ # TODO: nested run() will be merged into annotate() later
+ def run(ui, *pats, **opts):
+ repo = thgrepo.repository(ui, opts.get('root') or paths.find_root())
+ rev = scmutil.revsingle(repo, opts.get('rev')).rev()
+ filename = hglib.canonpaths(pats)[0]
+ dlg = filedialogs.FileLogDialog(repo, filename)
+ dlg.setFileViewMode(fileview.AnnMode)
+ dlg.goto(rev)
+ if opts.get('line'):
+ try:
+ lineno = int(opts['line'])
+ except ValueError:
+ raise util.Abort(_('invalid line number: %s') % opts['line'])
+ dlg.showLine(lineno)
+ if opts.get('pattern'):
+ dlg.setSearchPattern(hglib.tounicode(opts['pattern']))
+ return dlg
return qtrun(run, ui, *pats, **opts)

@command('archive',

Yuya Nishihara

unread,
Jun 1, 2013, 8:05:45 AM6/1/13
to thg...@googlegroups.com
# HG changeset patch
# User Yuya Nishihara <yu...@tcha.org>
# Date 1369566884 -32400
# Sun May 26 20:14:44 2013 +0900
# Node ID 6dd87c8b30586848b2273ca855d5a7fca9fb50c1
# Parent db9904c86e2fe52e5c259b179e6e0b76ab37b4ad
grep: extract internal method to open annotation

diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -648,9 +648,7 @@ class MatchTree(QTableView):
self.selectedRows = saved

def onAnnotateFile(self):
- from tortoisehg.hgqt.manifestdialog import run
- from tortoisehg.hgqt.run import qtrun
- repo, ui, pattern, icase = self.repo, self.repo.ui, self.pattern, self.icase
+ repo = self.repo
seen = set()
for rev, upath, line in self.selectedRows:
path = hglib.fromunicode(upath)
@@ -665,19 +663,21 @@ class MatchTree(QTableView):
if root and abs.startswith(root):
path = abs[len(root)+1:]
srepo = thgrepo.repository(None, root)
- if rev is None:
- rev = srepo['.'].rev()
- opts = {'repo': srepo, 'canonpath' : path, 'rev' : rev,
- 'line': line, 'pattern': pattern, 'ignorecase': icase}
- qtrun(run, ui, **opts)
+ self._openAnnotateDialog(srepo, rev, path, line)
else:
continue
else:
- if rev is None:
- rev = repo['.'].rev()
- opts = {'repo': repo, 'canonpath' : path, 'rev' : rev,
- 'line': line, 'pattern': pattern, 'ignorecase': icase}
- qtrun(run, ui, **opts)
+ self._openAnnotateDialog(repo, rev, path, line)
+
+ def _openAnnotateDialog(self, repo, rev, path, line):
+ from tortoisehg.hgqt.manifestdialog import run
+ from tortoisehg.hgqt.run import qtrun
+ ui, pattern, icase = self.repo.ui, self.pattern, self.icase
+ if rev is None:
+ rev = repo['.'].rev()
+ opts = {'repo': repo, 'canonpath' : path, 'rev' : rev,
+ 'line': line, 'pattern': pattern, 'ignorecase': icase}
+ qtrun(run, ui, **opts)

def onViewChangeset(self):
for rev, path, line in self.selectedRows:

Yuya Nishihara

unread,
Jun 1, 2013, 8:05:46 AM6/1/13
to thg...@googlegroups.com
# HG changeset patch
# User Yuya Nishihara <yu...@tcha.org>
# Date 1370087065 -32400
# Sat Jun 01 20:44:25 2013 +0900
# Node ID 5e8e69c85e8b2192191c381d31814b5327fdaac4
# Parent 6dd87c8b30586848b2273ca855d5a7fca9fb50c1
grep: open FileLogDialog for annotation

diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -11,6 +11,7 @@ import re
from mercurial import ui, hg, error, commands, match, util, subrepo

from tortoisehg.hgqt import htmlui, visdiff, qtlib, htmldelegate, thgrepo, cmdui, settings
+from tortoisehg.hgqt import filedialogs, fileview
from tortoisehg.util import paths, hglib, thread2
from tortoisehg.hgqt.i18n import _

@@ -670,8 +671,18 @@ class MatchTree(QTableView):
self._openAnnotateDialog(repo, rev, path, line)

def _openAnnotateDialog(self, repo, rev, path, line):
- from tortoisehg.hgqt.manifestdialog import run
from tortoisehg.hgqt.run import qtrun
+
+ # TODO: use DialogKeeper
+ def run(ui, *pats, **opts):
+ dlg = self._createFileDialog(opts['repo'], opts['canonpath'])
+ dlg.setFileViewMode(fileview.AnnMode)
+ dlg.goto(opts['rev'])
+ dlg.showLine(line)
+ dlg.setSearchPattern(hglib.tounicode(opts['pattern']))
+ dlg.setSearchCaseInsensitive(opts['ignorecase'])
+ return dlg
+
ui, pattern, icase = self.repo.ui, self.pattern, self.icase
if rev is None:
rev = repo['.'].rev()
@@ -679,6 +690,14 @@ class MatchTree(QTableView):
'line': line, 'pattern': pattern, 'ignorecase': icase}
qtrun(run, ui, **opts)

+ def _createFileDialog(self, repo, path):
+ # dirty hack to pass workbench only if available
+ from tortoisehg.hgqt import workbench # avoid cyclic dep
+ repoviewer = None
+ if isinstance(self.window(), workbench.Workbench):
+ repoviewer = self.window()
+ return filedialogs.FileLogDialog(repo, path, repoviewer=repoviewer)
+
def onViewChangeset(self):
for rev, path, line in self.selectedRows:
self.revisionSelected.emit(int(rev))

Yuya Nishihara

unread,
Jun 1, 2013, 8:05:47 AM6/1/13
to thg...@googlegroups.com
# HG changeset patch
# User Yuya Nishihara <yu...@tcha.org>
# Date 1370087725 -32400
# Sat Jun 01 20:55:25 2013 +0900
# Node ID b345715253766cda9e332c9dafc1a38c82f25ff8
# Parent 5e8e69c85e8b2192191c381d31814b5327fdaac4
grep: use DialogKeeper to manage annotate dialogs

diff --git a/tortoisehg/hgqt/grep.py b/tortoisehg/hgqt/grep.py
--- a/tortoisehg/hgqt/grep.py
+++ b/tortoisehg/hgqt/grep.py
@@ -563,6 +563,10 @@ class MatchTree(QTableView):
vh.setDefaultSectionSize(20)
self.horizontalHeader().setStretchLastSection(True)

+ self._filedialogs = qtlib.DialogKeeper(MatchTree._createFileDialog,
+ MatchTree._genFileDialogKey,
+ self)
+
self.actions = {}
self.contextmenu = QMenu(self)
for key, name, func, shortcut in (
@@ -671,24 +675,15 @@ class MatchTree(QTableView):
self._openAnnotateDialog(repo, rev, path, line)

def _openAnnotateDialog(self, repo, rev, path, line):
- from tortoisehg.hgqt.run import qtrun
-
- # TODO: use DialogKeeper
- def run(ui, *pats, **opts):
- dlg = self._createFileDialog(opts['repo'], opts['canonpath'])
- dlg.setFileViewMode(fileview.AnnMode)
- dlg.goto(opts['rev'])
- dlg.showLine(line)
- dlg.setSearchPattern(hglib.tounicode(opts['pattern']))
- dlg.setSearchCaseInsensitive(opts['ignorecase'])
- return dlg
-
- ui, pattern, icase = self.repo.ui, self.pattern, self.icase
if rev is None:
rev = repo['.'].rev()
- opts = {'repo': repo, 'canonpath' : path, 'rev' : rev,
- 'line': line, 'pattern': pattern, 'ignorecase': icase}
- qtrun(run, ui, **opts)
+
+ dlg = self._filedialogs.open(repo, path)
+ dlg.setFileViewMode(fileview.AnnMode)
+ dlg.goto(rev)
+ dlg.showLine(line)
+ dlg.setSearchPattern(hglib.tounicode(self.pattern))
+ dlg.setSearchCaseInsensitive(self.icase)

def _createFileDialog(self, repo, path):
# dirty hack to pass workbench only if available
@@ -698,6 +693,9 @@ class MatchTree(QTableView):
repoviewer = self.window()
return filedialogs.FileLogDialog(repo, path, repoviewer=repoviewer)

+ def _genFileDialogKey(self, repo, filename):
+ return repo.wjoin(filename)

Yuya Nishihara

unread,
Jun 1, 2013, 8:13:30 AM6/1/13
to thg...@googlegroups.com
On Sat, 01 Jun 2013 21:05:47 +0900, Yuya Nishihara wrote:
> def _createFileDialog(self, repo, path):
> # dirty hack to pass workbench only if available
> @@ -698,6 +693,9 @@ class MatchTree(QTableView):
> repoviewer = self.window()
> return filedialogs.FileLogDialog(repo, path, repoviewer=repoviewer)
>
> + def _genFileDialogKey(self, repo, filename):
> + return repo.wjoin(filename)

Oops. I'll rename "filename" variable to "path", because it should have the
same signature as _createFileDialog.

Regards.

Yuya Nishihara

unread,
Jun 7, 2013, 9:49:55 AM6/7/13
to thg...@googlegroups.com
On Sat, 01 Jun 2013 21:05:44 +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yu...@tcha.org>
> # Date 1370086486 -32400
> # Sat Jun 01 20:34:46 2013 +0900
> # Node ID db9904c86e2fe52e5c259b179e6e0b76ab37b4ad
> # Parent c7ed928b0021d2ba1f103f0c8f9390a675e31f1e
> annotate: use FileLogDialog instead of ManifestDialog
>
> Since annotate is file oriented, FileLogDialog is more suitable than
> ManifestDialog. You can still open ManifestDialog by "thg manifest".

Hi,

There's no -1, so I pushed this series to default. "thg annotate" command
will open FileLogDialog.

Regards,
Reply all
Reply to author
Forward
0 new messages