Commit fa24cbef authored by Steve Borho's avatar Steve Borho
Browse files

hgqt: mercurial handles tags, branches, and bookmarks in UTF-8

Local tags are stored in local encoding, but converted to UTF-8 when read.
Bookmarks, tags, and branch names are stored in UTF-8. Internal mercurial APIs
are all UTF-8.  Only commnd line arguments should be in local encoding.
parent 107612ad9515
......@@ -62,6 +62,7 @@ class BranchOpDialog(QDialog):
elif oldbranchop == False:
closebranch.setChecked(True)
else:
assert type(oldbranchop) == QString
bc = branchCombo
names = [bc.itemText(i) for i in xrange(bc.count())]
if oldbranchop in names:
......@@ -96,7 +97,7 @@ class BranchOpDialog(QDialog):
'''Branch operation is one of:
None - leave wctx branch name untouched
False - close current branch
str - open new named branch
QString - open new named branch
'''
if self.branchCombo.isEnabled():
self.branchop = self.branchCombo.currentText()
......
......@@ -21,7 +21,6 @@ from tortoisehg.hgqt.sync import loadIniFile
# Technical Debt for CommitWidget
# qtlib decode failure dialog (ask for retry locale, suggest HGENCODING)
# Need a unicode-to-UTF8 function
# spell check / tab completion
# in-memory patching / committing chunk selected files
......@@ -249,11 +248,11 @@ class CommitWidget(QWidget):
self.msgcombo.reset(self.msghistory)
# Update branch operation button
cur = hglib.tounicode(self.repo[None].branch())
branchu = unicode(self.repo[None].branch(), 'utf-8')
if self.branchop is None:
title = _('Branch: ') + cur
title = _('Branch: ') + branchu
elif self.branchop == False:
title = _('Close Branch: ') + cur
title = _('Close Branch: ') + branchu
else:
title = _('New Branch: ') + self.branchop
self.branchbutton.setText(title)
......@@ -520,30 +519,31 @@ class CommitWidget(QWidget):
brcmd = ['--close-branch']
else:
brcmd = []
# TODO: Need a unicode-to-UTF8 function
newbranch = hglib.fromunicode(self.branchop)
if newbranch in repo.branchtags():
# self.branchop - new branch name in QString (unicode)
# branchutf - new branch name in UTF8
branchutf = unicode(self.branchop).encode('utf-8')
if branchutf in repo.branchtags():
# response: 0=Yes, 1=No, 2=Cancel
if newbranch in [p.branch() for p in repo.parents()]:
if branchutf in [p.branch() for p in repo.parents()]:
resp = 0
else:
rev = repo[newbranch].rev()
rev = repo[branchutf].rev()
resp = qtlib.CustomPrompt(_('Confirm Branch Change'),
_('Named branch "%s" already exists, '
'last used in revision %d\n'
'Yes\t- Make commit restarting this named branch\n'
'No\t- Make commit without changing branch\n'
'Cancel\t- Cancel this commit') % (newbranch, rev),
'Cancel\t- Cancel this commit') % (self.branchop, rev),
self, (_('&Yes'), _('&No'), _('Cancel')), 2, 2).run()
else:
resp = qtlib.CustomPrompt(_('Confirm New Branch'),
_('Create new named branch "%s" with this commit?\n'
'Yes\t- Start new branch with this commit\n'
'No\t- Make commit without branch change\n'
'Cancel\t- Cancel this commit') % newbranch,
'Cancel\t- Cancel this commit') % self.branchop,
self, (_('&Yes'), _('&No'), _('Cancel')), 2, 2).run()
if resp == 0:
repo.dirstate.setbranch(newbranch)
repo.dirstate.setbranch(branchutf)
elif resp == 2:
return
files = self.stwidget.getChecked('MAR?!S')
......
......@@ -61,6 +61,7 @@ class HgRepoListModel(QAbstractTableModel):
_columns = ('Graph', 'ID', 'Branch', 'Log', 'Author', 'Age', 'Tags',)
_stretchs = {'Log': 1, }
_mqtags = ('qbase', 'qtip', 'qparent')
def __init__(self, repo, branch, revset, rfilter, parent):
"""
......@@ -92,7 +93,7 @@ class HgRepoListModel(QAbstractTableModel):
'Log': self.getlog,
'Author': self.getauthor,
'Tags': self.gettags,
'Branch': lambda ctx, gnode: ctx.branch(),
'Branch': self.getbranch,
'Filename': lambda ctx, gnode: gnode.extra[0],
'Age': lambda ctx, gnode: hglib.age(ctx.date()),
'LocalTime':lambda ctx, gnode: hglib.displaytime(ctx.date()),
......@@ -461,13 +462,14 @@ class HgRepoListModel(QAbstractTableModel):
self.datacache = {}
self.layoutChanged.emit()
def getbranch(self, ctx, gnode):
return unicode(ctx.branch(), 'utf-8')
def gettags(self, ctx, gnode):
if ctx.rev() is None:
return ""
mqtags = ['qbase', 'qtip', 'qparent']
tags = ctx.tags()
tags = [t for t in tags if t not in mqtags]
return hglib.tounicode(",".join(tags))
return ''
tags = [t for t in ctx.tags() if t not in self._mqtags]
return unicode(','.join(tags), 'utf-8')
def getauthor(self, ctx, gnode):
try:
......@@ -485,31 +487,39 @@ class HgRepoListModel(QAbstractTableModel):
if ctx.thgmqunappliedpatch():
effects = qtlib.geteffect('log.unapplied_patch')
text = qtlib.applyeffects(' %s ' % ctx._patchname, effects)
#return text + " " + qtlib.markup(msg, fg=UNAPPLIED_PATCH_COLOR)
return text + " " + msg
# qtlib.markup(msg, fg=UNAPPLIED_PATCH_COLOR)
return hglib.tounicode(text + ' ' + msg)
parts = []
if ctx.thgbranchhead():
branchu = unicode(ctx.branch(), 'utf-8')
effects = qtlib.geteffect('log.branch')
text = qtlib.applyeffects(' %s ' % ctx.branch(), effects)
parts.append(hglib.tounicode(text))
parts.append(qtlib.applyeffects(u' %s ' % branchu, effects))
# in the near future, I expect bookmarks to be available from the
# repository via a separate API, making this logic more efficient.
bookmarks = self.repo.bookmarks.keys()
curbookmark = self.repo.bookmarkcurrent
for tag in ctx.thgtags():
style = (self.repo.thgmqtag(tag) and 'log.patch'
or (tag == curbookmark and 'log.curbookmark'
or (tag in bookmarks and 'log.bookmark' or 'log.tag')))
if self.repo.thgmqtag(tag):
style = 'log.patch'
elif tag == curbookmark:
style = 'log.curbookmark'
elif tag in bookmarks:
style = 'log.bookmark'
else:
style = 'log.tag'
# tag is in UTF-8, we need it in unicode with style effects
tagu = unicode(tag, 'utf-8')
effects = qtlib.geteffect(style)
text = qtlib.applyeffects(' %s ' % tag, effects)
parts.append(hglib.tounicode(text))
parts.append(qtlib.applyeffects(u' %s ' % tagu, effects))
if msg:
if ctx.thgwdparent():
msg = qtlib.markup(msg, weight='bold')
else:
msg = qtlib.markup(msg)
parts.append(hglib.tounicode(msg))
parts.append(hglib.tounicode(msg))
return ' '.join(parts)
......
......@@ -235,7 +235,7 @@ class TagDialog(QDialog):
def add_tag(self):
local = self.local_chk.isChecked()
name = self.tag_combo.currentText()
lname = hglib.fromunicode(name)
nameutf = unicode(name).encode('utf-8')
rev = hglib.fromunicode(self.rev_text.text())
force = self.replace_chk.isChecked()
english = self.eng_chk.isChecked()
......@@ -243,7 +243,7 @@ class TagDialog(QDialog):
try:
# tagging
if lname in self.repo.tags() and not force:
if nameutf in self.repo.tags() and not force:
raise util.Abort(_("Tag '%s' already exist") % name)
ctx = self.repo[rev]
node = ctx.node()
......@@ -255,7 +255,7 @@ class TagDialog(QDialog):
message = hglib.fromunicode(message)
self.repo.incrementBusyCount()
self.repo.tag(lname, node, message, local, None, None)
self.repo.tag(nameutf, node, message, local, None, None)
self.repo.decrementBusyCount()
if local:
self.localTagChanged.emit()
......@@ -270,26 +270,26 @@ class TagDialog(QDialog):
def remove_tag(self):
local = self.local_chk.isChecked()
name = self.tag_combo.currentText()
lname = hglib.fromunicode(name)
nameutf = unicode(name).encode('utf-8')
english = self.eng_chk.isChecked()
message = hglib.fromunicode(self.custom_text.text())
try:
# tagging
tagtype = self.repo.tagtype(lname)
tagtype = self.repo.tagtype(nameutf)
if local:
if tagtype != 'local':
raise util.Abort(_('tag \'%s\' is not a local tag') % lname)
raise util.Abort(_('tag \'%s\' is not a local tag') % name)
else:
if tagtype != 'global':
raise util.Abort(_('tag \'%s\' is not a global tag') % lname)
raise util.Abort(_('tag \'%s\' is not a global tag') % name)
if not message:
msgset = keep._('Removed tag %s')
message = (english and msgset['id'] or msgset['str']) % name
self.repo.incrementBusyCount()
node = self.repo[-1].node()
self.repo.tag(lname, node, message, local, None, None)
self.repo.tag(nameutf, node, message, local, None, None)
self.repo.decrementBusyCount()
if local:
self.localTagChanged.emit()
......
......@@ -227,9 +227,9 @@ def _extendrepo(repo):
@propertycache
def _thghiddentags(self):
t = self.ui.config('tortoisehg', 'hidetags', '')
hiddentags_opt = hglib.tounicode(t)
return [t.strip() for t in hiddentags_opt.split()]
# Assume Mercurial.ini file is in local encoding, need UTF-8
ht = self.ui.config('tortoisehg', 'hidetags', '')
return [hglib.toutf(t).strip() for t in ht.split()]
@propertycache
def thgmqunappliedpatches(self):
......@@ -343,9 +343,9 @@ def _extendrepo(repo):
@propertycache
def deadbranches(self):
db = hglib.toutf(self.ui.config('tortoisehg', 'deadbranch', ''))
dblist = [b.strip() for b in db.split(',')]
return dblist
# Assume Mercurial.ini file is in local encoding, need UTF-8
db = self.ui.config('tortoisehg', 'deadbranch', '')
return [hglib.toutf(b).strip() for b in db.split(',')]
@propertycache
def displayname(self):
......@@ -481,21 +481,13 @@ def getcontext(repo, target):
def _extendchangectx(changectx):
class thgchangectx(changectx.__class__):
def _thgrawtags(self):
'''Returns the tags for self, converted to UTF-8 but
unfiltered for hidden tags'''
return [hglib.toutf(tag) for tag in self.tags()]
def thgtags(self):
'''Returns all unhidden tags for self, converted to UTF-8'''
value = self._thgrawtags()
'''Returns all unhidden tags for self in UTF-8'''
htlist = self._repo._thghiddentags
return [tag for tag in value if tag not in htlist]
return [tag for tag in self.tags() if tag not in htlist]
def thgwdparent(self):
'''True if self is a parent of the working directory'''
# FIXME doesn't handle error.Abort apparently raiseable by self._repo.parents()
# see old __init__ for repomodel
return self.rev() in [ctx.rev() for ctx in self._repo.parents()]
def _thgmqpatchtags(self):
......@@ -510,7 +502,8 @@ def _extendchangectx(changectx):
'''True if self is an MQ applied patch'''
return self.rev() is not None and bool(self._thgmqpatchtags())
def thgmqunappliedpatch(self): return False
def thgmqunappliedpatch(self):
return False
def thgmqpatchname(self):
'''Return self's MQ patch name. AssertionError if self not an MQ patch'''
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment