by
Changes to 49 files · Browse files at 474a14363dee Showing diff from parent dbe7b9b55bf1 ef48dc901ed8 Diff from another changeset...
@@ -51,3 +51,5 @@ dc23fbf831944fdf894cade250161131c11c9ce4 1.9.2
36a2bd08a405438ec776ad506c71fe581b8ce0b5 1.9.3
81a60ce2dba7178e834ac46b0c996bee38380e77 2.0
+ee531052f78b11dafe1d8c7ab9cfb95b4854be38 2.0.1
+5333ccf1184864720c1d3690df94fa47df80bf02 2.0.2
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
@@ -304,6 +304,7 @@ 'Background thread for annotating a file at a revision'
def __init__(self, parent=None):
super(_AnnotateThread, self).__init__(parent)
+ self._threadid = None
@pyqtSlot(object)
def start(self, fctx):
@@ -313,10 +314,12 @@
@pyqtSlot()
def abort(self):
+ if self._threadid is None:
+ return
try:
thread2._async_raise(self._threadid, KeyboardInterrupt)
self.wait()
- except (AttributeError, ValueError):
+ except ValueError:
pass
def run(self):
@@ -330,7 +333,7 @@ except KeyboardInterrupt:
pass
finally:
- del self._threadid
+ self._threadid = None
del self._fctx
class AnnotateDialog(QMainWindow):
|
@@ -20,11 +20,17 @@ def __init__(self, opts, parent=None):
super(BugReport, self).__init__(parent)
- self.text = self.gettext(opts)
+ layout = QVBoxLayout()
+ self.setLayout(layout)
- layout = QVBoxLayout()
+ lbl = QLabel(_('Please report this bug to our %s bug tracker %s') %
+ (u'<a href="http://bitbucket.org/tortoisehg/thg/wiki/BugReport">',
+ u'</a>'))
+ lbl.setOpenExternalLinks(True)
+ self.layout().addWidget(lbl)
tb = QTextBrowser()
+ self.text = self.gettext(opts)
tb.setHtml('<pre>' + Qt.escape(self.text) + '</pre>')
tb.setWordWrapMode(QTextOption.NoWrap)
layout.addWidget(tb)
@@ -35,19 +41,19 @@ bb.accepted.connect(self.accept)
bb.button(BB.Save).clicked.connect(self.save)
bb.button(BB.Ok).setDefault(True)
+ bb.addButton(_('Copy'), BB.HelpRole).clicked.connect(self.copyText)
bb.addButton(_('Quit'), BB.DestructiveRole).clicked.connect(qApp.quit)
layout.addWidget(bb)
- self.setLayout(layout)
self.setWindowTitle(_('TortoiseHg Bug Report'))
- self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
+ self.setWindowFlags(self.windowFlags() & \
+ ~Qt.WindowContextHelpButtonHint)
self.resize(650, 400)
self._readsettings()
def gettext(self, opts):
+ # TODO: make this more uniformly unicode safe
text = '{{{\n#!python\n' # Wrap in Bitbucket wiki preformat markers
- text += _('** Please report this bug to '
- 'http://bitbucket.org/tortoisehg/thg/issues\n')
text += '** Mercurial version (%s). TortoiseHg version (%s)\n' % (
hglib.hgversion, version.version())
text += '** Command: %s\n' % (hglib.tounicode(opts.get('cmd', 'N/A')))
@@ -62,6 +68,9 @@ text += '\n}}}'
return text
+ def copyText(self):
+ QApplication.clipboard().setText(self.text)
+
def getarch(self):
text = '** Windows version: %s\n' % str(sys.getwindowsversion())
arch = 'unknown (failed to import win32api)'
|
@@ -8,7 +8,7 @@ import cStringIO
import os
-from mercurial import hg, util, patch, commands
+from mercurial import hg, util, patch, commands, cmdutil
from mercurial import match as matchmod, ui as uimod
from hgext import record
@@ -100,27 +100,32 @@ self.refresh()
def runPatcher(self, fp, wfile, updatestate):
- class warncapt(uimod.ui):
+ ui = self.repo.ui.copy()
+ class warncapt(ui.__class__):
def warn(self, msg, *args, **opts):
self.write(msg)
+ ui.__class__ = warncapt
+
+ ok = True
repo = self.repo
- ui = warncapt()
ui.pushbuffer()
- strip, pfiles = 1, {}
- ok = True
+ pfiles = {}
+ curdir = os.getcwd()
try:
- patch.internalpatch(fp, ui, strip, repo.root, files=pfiles,
- eolmode=None)
+ os.chdir(repo.root)
+ if patch.applydiff(ui, fp, pfiles) < 0:
+ ok = False
+ self.showMessage.emit(_('Patch failed to apply'))
except patch.PatchError, err:
ok = False
self.showMessage.emit(hglib.tounicode(str(err)))
+ os.chdir(curdir)
for line in ui.popbuffer().splitlines():
if line.endswith(wfile + '.rej'):
if qtlib.QuestionMsgBox(_('Manually resolve rejected chunks?'),
hglib.tounicode(line) + u'<br><br>' +
_('Edit patched file and rejects?'),
parent=self):
- #wctxactions.edit(self, repo.ui, repo, [wfile, wfile+'.rej'])
from tortoisehg.hgqt import rejects
dlg = rejects.RejectsDialog(repo.wjoin(wfile), self)
if dlg.exec_() == QDialog.Accepted:
@@ -128,7 +133,7 @@ break
if updatestate and ok:
# Apply operations specified in git diff headers
- hglib.updatedir(repo.ui, repo, pfiles)
+ cmdutil.updatedir(repo.ui, repo, pfiles)
return ok
def editCurrentFile(self):
|
@@ -332,9 +332,13 @@
def _initfont(self):
tf = qtlib.getfont('fontoutputlog')
- tf.changed.connect(lambda f: self.setFont(f))
+ tf.changed.connect(self.forwardFont)
self.setFont(tf.font())
+ @pyqtSlot(QFont)
+ def forwardFont(self, font):
+ self.setFont(font)
+
def _initmarkers(self):
self._markers = {}
for l in ('ui.error', 'control'):
|
@@ -459,6 +459,7 @@ self.updateRecentMessages()
def addUsernameToHistory(self, user):
+ user = hglib.tounicode(user)
if user in self.userhist:
self.userhist.remove(user)
self.userhist.insert(0, user)
|
|
|
@@ -8,7 +8,7 @@ import os
import re
-from mercurial import ui, hg, error, commands, match, util
+from mercurial import ui, hg, error, commands, match, util, subrepo
from tortoisehg.hgqt import htmlui, visdiff, qtlib, htmldelegate, thgrepo, cmdui
from tortoisehg.util import paths, hglib, thread2
@@ -322,18 +322,22 @@ pass
def searchfinished(self):
- count = self.tv.model().rowCount(None)
- if not count:
- self.showMessage.emit(_('No matches found'))
- else:
- self.showMessage.emit(_('%d matches found') % count)
- for col in xrange(COL_TEXT):
- self.tv.resizeColumnToContents(col)
- self.tv.setSortingEnabled(True)
self.cancelbutton.setEnabled(False)
self.searchbutton.setEnabled(True)
self.regexple.setEnabled(True)
self.regexple.setFocus()
+ count = self.tv.model().rowCount(None)
+ if count:
+ for col in xrange(COL_TEXT):
+ self.tv.resizeColumnToContents(col)
+ self.tv.setSortingEnabled(True)
+ if self.thread.completed == False:
+ # do not overwrite error message on failure
+ pass
+ elif count:
+ self.showMessage.emit(_('%d matches found') % count)
+ else:
+ self.showMessage.emit(_('No matches found'))
class DataWrapper(object):
def __init__(self, data):
@@ -353,6 +357,7 @@ self.inc = inc
self.exc = exc
self.follow = follow
+ self.completed = False
def cancel(self):
if self.isRunning() and hasattr(self, 'thread_id'):
@@ -405,6 +410,7 @@ self.showMessage.emit(_('Interrupted'))
self.progress.emit(*cmdui.stopProgress(_('Searching')))
os.chdir(cwd)
+ self.completed = True
class CtxSearchThread(QThread):
'''Background thread for searching a changectx'''
@@ -421,49 +427,65 @@ self.exc = exc
self.once = once
self.canceled = False
+ self.completed = False
def cancel(self):
self.canceled = True
def run(self):
- hu = htmlui.htmlui()
- rev = self.ctx.rev()
- # generate match function relative to repo root
- matchfn = match.match(self.repo.root, '', [], self.inc, self.exc)
def badfn(f, msg):
e = hglib.tounicode("%s: %s" % (matchfn.rel(f), msg))
self.showMessage.emit(e)
- matchfn.bad = badfn
+ self.hu = htmlui.htmlui()
+ try:
+ # generate match function relative to repo root
+ matchfn = match.match(self.repo.root, '', [], self.inc, self.exc)
+ matchfn.bad = badfn
+ self.searchRepo(self.ctx, '', matchfn)
+ self.completed = True
+ except Exception, e:
+ self.showMessage.emit(hglib.tounicode(str(e)))
+ def searchRepo(self, ctx, prefix, matchfn):
topic = _('Searching')
unit = _('files')
- total = len(self.ctx.manifest())
+ total = len(ctx.manifest())
count = 0
- for wfile in self.ctx: # walk manifest
+ for wfile in ctx: # walk manifest
if self.canceled:
break
self.progress.emit(topic, count, wfile, unit, total)
count += 1
if not matchfn(wfile):
continue
- data = self.ctx[wfile].data() # load file data
+ data = ctx[wfile].data() # load file data
if util.binary(data):
continue
for i, line in enumerate(data.splitlines()):
pos = 0
for m in self.regexp.finditer(line): # perform regexp
- hu.write(line[pos:m.start()], label='ui.status')
- hu.write(line[m.start():m.end()], label='grep.match')
+ self.hu.write(line[pos:m.start()], label='ui.status')
+ self.hu.write(line[m.start():m.end()], label='grep.match')
pos = m.end()
if pos:
- hu.write(line[pos:], label='ui.status')
- row = [wfile, i + 1, rev, None, hu.getdata()[0]]
+ self.hu.write(line[pos:], label='ui.status')
+ path = os.path.join(prefix, wfile)
+ row = [path, i + 1, ctx.rev(), None, self.hu.getdata()[0]]
w = DataWrapper(row)
self.matchedRow.emit(w)
if self.once:
break
self.progress.emit(topic, None, '', '', None)
+ if ctx.rev() is None:
+ for s in ctx.substate:
+ if not matchfn(s):
+ continue
+ sub = ctx.sub(s)
+ if isinstance(sub, subrepo.hgsubrepo):
+ newprefix = os.path.join(prefix, s)
+ self.searchRepo(sub._repo[None], newprefix, lambda x: True)
+
COL_PATH = 0
COL_LINE = 1
@@ -589,10 +611,19 @@ continue
else:
seen.add(path)
+ if rev is None and path not in repo[None]:
+ abs = repo.wjoin(path)
+ root = paths.find_root(abs)
+ if root and abs.startswith(root):
+ path = abs[len(root)+1:]
+ else:
+ continue
+ else:
+ root = repo.root
dlg = annotate.AnnotateDialog(path, rev=rev, line=line,
pattern=pattern, parent=self,
searchwidget=self.parent(),
- root=repo.root)
+ root=root)
dlg.show()
def onViewChangeset(self):
|
@@ -283,18 +283,22 @@ w.setUtf8(True)
w.setReadOnly(True)
w.setMarginWidth(1, 0) # hide area for line numbers
- lex = lexers.get_diff_lexer(self)
+ self.lexer = lex = lexers.get_diff_lexer(self)
fh = qtlib.getfont('fontdiff')
- fh.changed.connect(lambda f: lex.setFont(f))
- # TODO: why cannot we connect directly, without lambda?
+ fh.changed.connect(self.forwardFont)
lex.setFont(fh.font())
w.setLexer(lex)
# TODO: better way to setup diff lexer
+
initqsci(self._qui.preview_edit)
self._qui.main_tabs.currentChanged.connect(self._refreshpreviewtab)
self._refreshpreviewtab(self._qui.main_tabs.currentIndex())
+ def forwardFont(self, font):
+ if self.lexer:
+ self.lexer.setFont(font)
+
@pyqtSlot(int)
def _refreshpreviewtab(self, index):
"""Generate preview text if current tab is preview"""
|
@@ -224,7 +224,7 @@ self.repo.thginvalidate()
wctx = self.repo[None]
wctx.status(unknown=True)
- except error.RepoError, e:
+ except (EnvironmentError, error.RepoError), e:
qtlib.WarningMsgBox(_('Unable to read repository status'),
uni(str(e)), parent=self)
except util.Abort, e:
|
@@ -176,7 +176,8 @@ qs.setValue(prefix+'/splitter', self._splitter.saveState())
def _initactions(self):
- self._statusfilter = _StatusFilterButton(statustext='MAC')
+ self._statusfilter = status.StatusFilterButton(
+ statustext='MAC', text=_('Status'))
self._toolbar.addWidget(self._statusfilter)
self._action_annotate_mode = QAction(_('Annotate'), self, checkable=True)
@@ -405,51 +406,6 @@ def _emitPathChanged(self):
self.pathChanged.emit(self.path)
-# TODO: share this menu with status widget?
-class _StatusFilterButton(QToolButton):
- """Button with drop-down menu for status filter"""
- statusChanged = pyqtSignal(str)
-
- _TYPES = 'MARC'
-
- def __init__(self, statustext=_TYPES, parent=None, **kwargs):
- if 'text' not in kwargs:
- kwargs['text'] = _('Status')
- super(_StatusFilterButton, self).__init__(
- parent, popupMode=QToolButton.InstantPopup,
- icon=qtlib.geticon('hg-status'),
- toolButtonStyle=Qt.ToolButtonTextBesideIcon, **kwargs)
-
- self._initactions(statustext)
-
- def _initactions(self, text):
- self._actions = {}
- menu = QMenu(self)
- for c in self._TYPES:
- st = status.statusTypes[c]
- a = menu.addAction('%s %s' % (c, st.name))
- a.setCheckable(True)
- a.setChecked(c in text)
- a.toggled.connect(self._update)
- self._actions[c] = a
- self.setMenu(menu)
-
- @pyqtSlot()
- def _update(self):
- self.statusChanged.emit(self.status())
-
- def status(self):
- """Return the text for status filter"""
- return ''.join(c for c in self._TYPES
- if self._actions[c].isChecked())
-
- @pyqtSlot(str)
- def setStatus(self, text):
- """Set the status text"""
- assert util.all(c in self._TYPES for c in text)
- for c in self._TYPES:
- self._actions[c].setChecked(c in text)
-
class ManifestTaskWidget(ManifestWidget):
"""Manifest widget designed for task tab"""
|
@@ -172,7 +172,7 @@ def _rootentry(self):
try:
return self.__rootentry
- except AttributeError:
+ except (AttributeError, TypeError):
self._buildrootentry()
return self.__rootentry
|
@@ -223,6 +223,7 @@ return (fullsrc.upper() == fulldest.upper() and sys.platform == 'win32')
def compose_command(self, src, dest):
+ 'src and dest are expected to be in local encoding'
if self.copy_chk.isChecked():
cmdline = ['copy']
else:
@@ -231,8 +232,8 @@ cmdline.append('-v')
if self.isCaseFoldingOnWin():
cmdline.append('-A')
- cmdline.append(hglib.fromunicode(src))
- cmdline.append(hglib.fromunicode(dest))
+ cmdline.append(src)
+ cmdline.append(dest)
vcmdline = ' '.join(['hg'] + cmdline)
return (cmdline, vcmdline)
|
@@ -509,11 +509,19 @@
def getlog(self, ctx, gnode):
if ctx.rev() is None:
+ msg = None
if self.unicodestar:
# The Unicode symbol is a black star:
- return u'\u2605 ' + _('Working Directory') + u' \u2605'
+ msg = u'\u2605 ' + _('Working Directory') + u' \u2605'
else:
- return '*** ' + _('Working Directory') + ' ***'
+ msg = '*** ' + _('Working Directory') + ' ***'
+
+ for pctx in ctx.parents():
+ if pctx.node() not in self.repo._branchheads:
+ text = _('Not a head revision!')
+ msg += " " + qtlib.markup(text, fg='red', weight='bold')
+
+ return msg
msg = ctx.longsummary()
@@ -521,6 +529,7 @@ effects = qtlib.geteffect('log.unapplied_patch')
text = qtlib.applyeffects(' %s ' % ctx._patchname, effects)
# qtlib.markup(msg, fg=UNAPPLIED_PATCH_COLOR)
+ msg = qtlib.markup(msg)
return hglib.tounicode(text + ' ' + msg)
parts = []
|
@@ -72,6 +72,11 @@ self.workbench.showMessage(self.msg)
super(RepoTreeView, self).mouseMoveEvent(event)
+ def keyPressEvent(self, event):
+ if event.key() in (Qt.Key_Enter, Qt.Key_Return):
+ self.showFirstTabOrOpen()
+ else:
+ super(RepoTreeView, self).keyPressEvent(event)
def leaveEvent(self, event):
if self.msg != '':
self.workbench.showMessage('')
|
@@ -244,33 +244,24 @@
key = '%s/column_widths/%s' % (self.cfgname, str(self.repo[0]))
s.setValue(key, col_widths)
- s.setValue('%s/widget_width' % self.cfgname, self.viewport().width())
def resizeEvent(self, e):
# re-size columns the smart way: the column holding Description
# is re-sized according to the total widget size.
- if e.oldSize().width() != e.size().width():
- key = '%s/widget_width' % self.cfgname
- widget_width, ok = QSettings().value(key).toInt()
- if not ok:
- widget_width = 0
+ if self.resized and e.oldSize().width() != e.size().width():
+ model = self.model()
+ total_width = stretch_col = 0
- if self.resized:
- model = self.model()
- vp_width = self.viewport().width()
- total_width = stretch_col = 0
+ for c in range(model.columnCount(QModelIndex())):
+ if model._columns[c] in model._stretchs:
+ #save the description column
+ stretch_col = c
+ else:
+ #total the other widths
+ total_width += self.columnWidth(c)
- if vp_width != widget_width:
- for c in range(model.columnCount(QModelIndex())):
- if model._columns[c] in model._stretchs:
- #save the description column
- stretch_col = c
- else:
- #total the other widths
- total_width += self.columnWidth(c)
-
- width = max(vp_width - total_width, 100)
- self.setColumnWidth(stretch_col, width)
+ width = max(self.viewport().width() - total_width, 100)
+ self.setColumnWidth(stretch_col, width)
super(HgRepoView, self).resizeEvent(e)
|
@@ -148,7 +148,7 @@ self.message.setMinimumSize(QSize(0, 0))
f = getfont('fontcomment')
self.message.setFont(f.font())
- f.changed.connect(lambda font: self.message.setFont(font))
+ f.changed.connect(self.forwardFont)
self.fileview = HgFileView(self.repo, self.message_splitter)
sp = SP(SP.Expanding, SP.Expanding)
@@ -169,6 +169,9 @@ self.filelist.fileRevSelected.connect(self.onFileRevSelected)
self.filelist.clearDisplay.connect(self.fileview.clearDisplay)
+ def forwardFont(self, font):
+ self.message.setFont(font)
+
def createActions(self):
def fileActivated():
idx = self.filelist.currentIndex()
|
|
@@ -104,10 +104,23 @@ else:
lbl = QLabel(_('Filter:'))
hbox.addWidget(lbl)
- pb = QPushButton(_('Status'))
- hbox.addWidget(le)
- hbox.addWidget(pb)
- hbox.addWidget(tb)
+
+ st = ''
+ for s in statusTypes:
+ val = statusTypes[s]
+ if self.opts[val.name]:
+ st = st + s
+ self.statusfilter = StatusFilterButton(
+ statustext=st, types=StatusType.preferredOrder)
+
+ self.filelistToolbar = QToolBar(_('Status File List Toolbar'))
+ self.filelistToolbar.setIconSize(QSize(16,16))
+ hbox.addWidget(self.filelistToolbar)
+ self.filelistToolbar.addWidget(le)
+ self.filelistToolbar.addSeparator()
+ self.filelistToolbar.addWidget(self.statusfilter)
+ self.filelistToolbar.addSeparator()
+ self.filelistToolbar.addWidget(self.refreshBtn)
tv = WctxFileTree(self.repo)
vbox.addLayout(hbox)
vbox.addWidget(tv)
@@ -146,18 +159,14 @@ tv.clicked.connect(self.onRowClicked)
le.textEdited.connect(self.setFilter)
- def statusTypeTrigger(isChecked):
- txt = hglib.fromunicode(self.sender().text())
- self.opts[txt[2:]] = isChecked
+ def statusTypeTrigger(status):
+ status = str(status)
+ for s in statusTypes:
+ val = statusTypes[s]
+ self.opts[val.name] = s in status
self.refreshWctx()
- menu = QMenu(self)
- for stat in StatusType.preferredOrder:
- val = statusTypes[stat]
- a = menu.addAction('%s %s' % (stat, val.name))
- a.setCheckable(True)
- a.setChecked(self.opts[val.name])
- a.triggered.connect(statusTypeTrigger)
- pb.setMenu(menu)
+ self.statusfilter.statusChanged.connect(statusTypeTrigger)
+
self.tv = tv
self.le = le
@@ -728,6 +737,52 @@ 'status.subrepo'),
}
+
+class StatusFilterButton(QToolButton):
+ """Button with drop-down menu for status filter"""
+ statusChanged = pyqtSignal(str)
+
+ def __init__(self, statustext, types=None, parent=None, **kwargs):
+ self._TYPES = 'MARC'
+ if types is not None:
+ self._TYPES = types
+ #if 'text' not in kwargs:
+ # kwargs['text'] = _('Status')
+ super(StatusFilterButton, self).__init__(
+ parent, popupMode=QToolButton.InstantPopup,
+ icon=qtlib.geticon('hg-status'),
+ toolButtonStyle=Qt.ToolButtonTextBesideIcon, **kwargs)
+
+ self._initactions(statustext)
+
+ def _initactions(self, text):
+ self._actions = {}
+ menu = QMenu(self)
+ for c in self._TYPES:
+ st = statusTypes[c]
+ a = menu.addAction('%s %s' % (c, st.name))
+ a.setCheckable(True)
+ a.setChecked(c in text)
+ a.toggled.connect(self._update)
+ self._actions[c] = a
+ self.setMenu(menu)
+
+ @pyqtSlot()
+ def _update(self):
+ self.statusChanged.emit(self.status())
+
+ def status(self):
+ """Return the text for status filter"""
+ return ''.join(c for c in self._TYPES
+ if self._actions[c].isChecked())
+
+ @pyqtSlot(str)
+ def setStatus(self, text):
+ """Set the status text"""
+ assert util.all(c in self._TYPES for c in text)
+ for c in self._TYPES:
+ self._actions[c].setChecked(c in text)
+
class StatusDialog(QDialog):
'Standalone status browser'
def __init__(self, pats, opts, root=None, parent=None):
|
@@ -258,6 +258,7 @@ self.setUrl(self.paths['default'])
self.curalias = 'default'
else:
+ self.setUrl('')
self.curalias = None
def refreshStatusTips(self):
@@ -728,7 +729,8 @@ def outputnodes(ret, data):
if ret == 0:
nodes = [n for n in data.splitlines() if len(n) == 40]
- self.outgoingNodes.emit(nodes)
+ if nodes:
+ self.outgoingNodes.emit(nodes)
self.showMessage.emit(_('%d outgoing changesets to %s') %
(len(nodes), urlu))
elif ret == 1:
|
@@ -26,6 +26,14 @@ from PyQt4.QtCore import *
from PyQt4.QtGui import *
+class ThgTabBar(QTabBar):
+ def mouseReleaseEvent(self, event):
+
+ if event.button() == Qt.MidButton:
+ self.tabCloseRequested.emit(self.tabAt(event.pos()))
+
+ super(QTabBar, self).mouseReleaseEvent(event)
+
class Workbench(QMainWindow):
"""hg repository viewer/browser application"""
finished = pyqtSignal(int)
@@ -74,6 +82,7 @@ self.setWindowIcon(qtlib.geticon('hg-log'))
self.repoTabsWidget = tw = QTabWidget()
+ tw.setTabBar(ThgTabBar())
tw.setDocumentMode(True)
tw.setTabsClosable(True)
tw.setMovable(True)
@@ -448,7 +457,6 @@ index = self.repoTabsWidget.currentIndex()
if widget.closeRepoWidget():
self.repoTabsWidget.removeTab(index)
- widget.deleteLater()
self.updateMenu()
def repoTabCloseRequested(self, index):
@@ -456,7 +464,6 @@ w = tw.widget(index)
if w and w.closeRepoWidget():
tw.removeTab(index)
- w.deleteLater()
self.updateMenu()
def repoTabChanged(self, index=0):
|
@@ -194,7 +194,7 @@ fp.seek(0)
return newini(fp)
else:
- fp = open(path, 'rb')
+ fp = util.posixfile(path, 'rb')
try:
return newini(fp)
finally:
|
Loading...