Commits

Yuya Nishihara committed fbb12cf

fixing infobar

Comments (0)

Files changed (14)

+# HG changeset patch
+# Parent d533e14e006b51188b723e2baef973cf5d568ba9
+
+diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
+--- a/tortoisehg/hgqt/qtlib.py
++++ b/tortoisehg/hgqt/qtlib.py
+@@ -734,6 +734,25 @@ class LabeledSeparator(QWidget):
+ 
+         self.setLayout(box)
+ 
++class ElidableLabel(QLabel):
++    def minimumSizeHint(self):
++        size = super(ElidableLabel, self).minimumSizeHint()
++        size.setWidth(0)  # XXX
++        return size
++
++    def paintEvent(self, event):
++        fm = self.fontMetrics()
++        if fm.width(self.text()) <= self.contentsRect().width():
++            return super(ElidableLabel, self).paintEvent(event)
++
++        s = fm.elidedText(self.text(), Qt.ElideRight,
++                          self.contentsRect().width(), Qt.TextShowMnemonic)
++        p = QPainter(self)
++        try:
++            p.drawText(0, fm.ascent(), s)
++        finally:
++            p.end()
++
+ class InfoBar(QFrame):
+     """Non-modal confirmation/alert (like web flash or Chrome's InfoBar)
+ 
+@@ -794,8 +813,8 @@ class StatusInfoBar(InfoBar):
+     """Show status message"""
+     def __init__(self, message, parent=None):
+         super(StatusInfoBar, self).__init__(parent)
+-        self._msglabel = QLabel(message, self,
+-                                textInteractionFlags=Qt.TextSelectableByMouse)
++        self._msglabel = ElidableLabel(message, self)
++        self._msglabel.setTextInteractionFlags(Qt.TextSelectableByMouse)
+         self.addWidget(self._msglabel)
+ 
+ class CommandErrorInfoBar(InfoBar):
+@@ -805,8 +824,8 @@ class CommandErrorInfoBar(InfoBar):
+     def __init__(self, message, parent=None):
+         super(CommandErrorInfoBar, self).__init__(parent)
+ 
+-        self._msglabel = QLabel(message, self,
+-                                textInteractionFlags=Qt.TextSelectableByMouse)
++        self._msglabel = ElidableLabel(message, self)
++        self._msglabel.setTextInteractionFlags(Qt.TextSelectableByMouse)
+         self.addWidget(self._msglabel)
+ 
+         self._loglabel = QLabel('<a href="log:">%s</a>' % _('Show Log'))
+@@ -822,8 +841,8 @@ class ConfirmInfoBar(InfoBar):
+     def __init__(self, message, parent=None):
+         super(ConfirmInfoBar, self).__init__(parent)
+ 
+-        self._msglabel = QLabel(message, self,
+-                                textInteractionFlags=Qt.TextSelectableByMouse)
++        self._msglabel = ElidableLabel(message, self)
++        self._msglabel.setTextInteractionFlags(Qt.TextSelectableByMouse)
+         self.addWidget(self._msglabel)
+ 
+         self._buttons = QDialogButtonBox(self)

filedata-dbg.diff

+# HG changeset patch
+# Parent 9add2d4511ce4f1395be4029575cfd29040442c1
+diff --git a/tortoisehg/hgqt/filedata.py b/tortoisehg/hgqt/filedata.py
+--- a/tortoisehg/hgqt/filedata.py
++++ b/tortoisehg/hgqt/filedata.py
+@@ -31,6 +31,7 @@ class FileData(object):
+         p = _('File or diffs not displayed: ')
+         try:
+             fctx = ctx.filectx(wfile)
++            print repr(fctx)
+             if ctx.rev() is None:
+                 size = fctx.size()
+             else:
+@@ -326,5 +327,6 @@ class FileData(object):
+         revs = [str(ctx), str(ctx2)]
+         diffopts = patch.diffopts(repo.ui, {})
+         diffopts.git = False
++        print 'diff', repr(olddata), repr(newdata), repr(ctx), repr(ctx2)
+         self.diff = mdiff.unidiff(olddata, olddate, newdata, newdate,
+                                   oldname, wfile, revs, diffopts)

flashmsg.diff

-# HG changeset patch
-# Parent 137a83e62c6bdcbdf887122804dce58c3cb88f90
-qtlib, repowidget: XXX add FlashMessage for incoming/outgoing preview
-
-NOT FULLY IMPLEMENTED YET. There are many TODOs and FIXMEs.
-The confirmation dialog, "push to remote repository?", isn't skipped yet.
-
-diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
---- a/tortoisehg/hgqt/qtlib.py
-+++ b/tortoisehg/hgqt/qtlib.py
-@@ -728,6 +728,76 @@ class LabeledSeparator(QWidget):
- 
-         self.setLayout(box)
- 
-+class FlashMessage(QFrame):
-+    """Widget like a web flash; alternative for message box or status bar"""
-+
-+    # TODO
-+    _commonstyle = '''
-+    .FlashMessage {
-+        margin: 0; padding: 2px; border: 1px solid #ccc;
-+        %(extra)s;
-+    }
-+    '''
-+    _statusstyles = {'success': 'background-color: #e7f9e0',
-+                     'error': 'background-color: #f9d8d8'}
-+
-+    _rejected = pyqtSignal()
-+
-+    def __init__(self, parent=None):
-+        super(FlashMessage, self).__init__(parent, visible=False)
-+        self.setLayout(QHBoxLayout())
-+        self.layout().setContentsMargins(0, 0, 0, 0)
-+
-+        self._closebutton = QPushButton(self, flat=True, autoDefault=False,
-+            icon=self.style().standardIcon(QStyle.SP_DockWidgetCloseButton))
-+        self._closebutton.clicked.connect(self.clearMessage)
-+        self.layout().addWidget(self._closebutton)
-+
-+        self._msglabel = QLabel(self)
-+        self.layout().addWidget(self._msglabel, stretch=1)
-+
-+        self._actionbutton = QPushButton(self)
-+        self._actionbutton.hide()
-+        self.layout().addWidget(self._actionbutton)
-+
-+    # TODO: handle enter and escape keys
-+
-+    @pyqtSlot(unicode)
-+    def showMessage(self, message, status='success'):
-+        self._msglabel.setText(message)
-+        self.setStyleSheet(self._commonstyle
-+                           % {'extra': self._statusstyles[status]})
-+        self.show()
-+        if self._actionbutton.isVisible():
-+            self._actionbutton.setFocus()
-+
-+    @pyqtSlot()
-+    def clearMessage(self):
-+        self._rejected.emit()
-+        self.hide()
-+        self._clearDefaultAction()
-+
-+    def setDefaultAction(self, text, acceptslot, rejectslot=None):
-+        self._clearDefaultAction()
-+        self._actionbutton.setText(text)
-+        self._actionbutton.clicked.connect(acceptslot)
-+        self._actionbutton.clicked.connect(self._clearDefaultAction)
-+        if rejectslot:
-+            self._rejected.connect(rejectslot)
-+        self._actionbutton.show()
-+
-+    @pyqtSlot()
-+    def _clearDefaultAction(self):
-+        try:
-+            self._actionbutton.clicked.disconnect()
-+        except TypeError:  # no existing signal-slot connection
-+            pass
-+        try:
-+            self._rejected.disconnect()
-+        except TypeError:  # no existing signal-slot connection
-+            pass
-+        self._actionbutton.hide()
-+
- class WidgetGroups(object):
-     """ Support for bulk-updating properties of Qt widgets """
- 
-diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
---- a/tortoisehg/hgqt/repowidget.py
-+++ b/tortoisehg/hgqt/repowidget.py
-@@ -97,6 +97,9 @@ class RepoWidget(QWidget):
-         self.layout().setContentsMargins(0, 0, 0, 0)
-         self.layout().setSpacing(0)
- 
-+        self._flashmsg = qtlib.FlashMessage()
-+        self.layout().addWidget(self._flashmsg)
-+
-         hbox = QHBoxLayout()
-         hbox.setContentsMargins(0, 0, 0, 0)
-         hbox.setSpacing(0)
-@@ -308,12 +311,12 @@ class RepoWidget(QWidget):
-         self.repoview.setRepo(self.repo)
-         self.revDetailsWidget.setRepo(self.repo)
-         self.manifestDemand.forward('setRepo', self.repo)
--        self.bundleAccept.setHidden(False)
--        self.bundleReject.setHidden(False)
--        self.filterbar.revsetle.setText('incoming()')
--        self.filterbar.setEnableFilter(False)
--        self.filterbar.show()
--        self.toolbarVisibilityChanged.emit()
-+        #self.bundleAccept.setHidden(False)
-+        #self.bundleReject.setHidden(False)
-+        #self.filterbar.revsetle.setText('incoming()')
-+        #self.filterbar.setEnableFilter(False)
-+        #self.filterbar.show()
-+        #self.toolbarVisibilityChanged.emit()
-         self.titleChanged.emit(self.title())
-         newlen = len(self.repo)
-         self.revset = range(oldlen, newlen)
-@@ -322,6 +325,11 @@ class RepoWidget(QWidget):
-         self.repoview.resetBrowseHistory(self.revset)
-         self._reload_rev = self.revset[0]
- 
-+        # XXX: just for testing flash msg
-+        self._flashmsg.setDefaultAction(_('Accept'),
-+                                        self.acceptBundle, self.rejectBundle)
-+        self._flashmsg.showMessage(_('Incoming changesets'))
-+
-     def clearBundle(self):
-         self.bundleAccept.setHidden(True)
-         self.bundleReject.setHidden(True)
-@@ -403,10 +411,14 @@ class RepoWidget(QWidget):
-             self.repoview.resetBrowseHistory(self.revset, self.rev)
- 
-     def setOutgoingNodes(self, nodes):
--        self.filterbar.revsetle.setText('outgoing()')
--        self.filterbar.show()
--        self.toolbarVisibilityChanged.emit()
-+        #self.filterbar.revsetle.setText('outgoing()')
-+        #self.filterbar.show()
-+        #self.toolbarVisibilityChanged.emit()
-         self.setRevisionSet([self.repo[n].rev() for n in nodes])
-+        # XXX: just for testing flash msg
-+        self._flashmsg.setDefaultAction(_('Push'),
-+                                        self.push,  # XXX push to current URL
-+                                        self.clearRevisionSet)
- 
-     def createGrepWidget(self):
-         upats = {}
-@@ -445,6 +457,14 @@ class RepoWidget(QWidget):
-         if self.isVisible():
-             self.showMessageSignal.emit(msg)
- 
-+        # XXX: just for testing flash message
-+        if msg and 'aborted' in msg:  # XXX
-+            self._flashmsg.showMessage(msg, status='error')
-+        elif msg:
-+            self._flashmsg.showMessage(msg)
-+        elif self._flashmsg._actionbutton.isHidden():  # XXX
-+            self._flashmsg.clearMessage()
-+
-     def showEvent(self, event):
-         QWidget.showEvent(self, event)
-         self.showMessageSignal.emit(self.currentMessage)

infobar-clicked.diff

+# HG changeset patch
+# Parent ebc688d14817f5fa0fa9da014929d813a557096e
+repowidget: not clear infobar on revision selected programatically (fixes #1043)
+
+This fixes the problem that clearRevisionSet() triggers disappearance of
+"pull completed" message, because of revisionSelected signal.
+
+diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
+--- a/tortoisehg/hgqt/repowidget.py
++++ b/tortoisehg/hgqt/repowidget.py
+@@ -741,6 +741,7 @@ class RepoWidget(QWidget):
+ 
+     def onRevisionClicked(self, rev):
+         'User clicked on a repoview row'
++        self.clearInfoBar(qtlib.InfoBar.INFO)
+         tw = self.taskTabsWidget
+         cw = tw.currentWidget()
+         if not cw.canswitch():
+@@ -756,7 +757,6 @@ class RepoWidget(QWidget):
+     def onRevisionSelected(self, rev):
+         'View selection changed, could be a reload'
+         self.showMessage('')
+-        self.clearInfoBar(qtlib.InfoBar.INFO)
+         if self.repomodel.graph is None:
+             return
+         try:

infobar-stacked.diff

+# HG changeset patch
+# Parent e449f27db26a179082f170608f83124a2a97b391
+
+diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
+--- a/tortoisehg/hgqt/repowidget.py
++++ b/tortoisehg/hgqt/repowidget.py
+@@ -102,7 +102,7 @@ class RepoWidget(QWidget):
+         self.layout().setContentsMargins(0, 0, 0, 0)
+         self.layout().setSpacing(0)
+ 
+-        self._infobarlayout = QVBoxLayout()  # placeholder for InfoBar
++        self._infobarlayout = QStackedLayout()  # placeholder for InfoBar
+         self.layout().addLayout(self._infobarlayout)
+ 
+         self.filterbar = RepoFilterBar(self.repo, self)
+@@ -231,28 +231,23 @@ class RepoWidget(QWidget):
+     def setInfoBar(self, cls, *args, **kwargs):
+         """Show the given infobar at top of RepoWidget
+ 
+-        If the priority of the current infobar is higher than new one,
+-        the request is silently ignored.
++        It closes the current infobar if its priority is lower or the same.
++        Otherwise newly created infobar isn't visible until the current
++        infobar is closed.
+         """
+-        cleared = self.clearInfoBar(priority=cls.infobartype)
+-        if not cleared:
+-            return
++        self.clearInfoBar(priority=cls.infobartype)
+         w = cls(*args, **kwargs)
+         w.linkActivated.connect(self._openLink)
+-        self._infobarlayout.insertWidget(0, w)
++        self._infobarlayout.addWidget(w)
+         w.setFocus()  # to handle key press by InfoBar
+         return w
+ 
+     def clearInfoBar(self, priority=None):
+-        """Close current infobar if available; return True if got empty"""
+-        it = self._infobarlayout.itemAt(0)
+-        if not it:
+-            return True
+-        if priority is None or it.widget().infobartype <= priority:
+-            it.widget().close()
+-            return True
+-        else:
+-            return False
++        """Close current infobar if available"""
++        for i in xrange(self._infobarlayout.count()):
++            w = self._infobarlayout.widget(i)
++            if priority is None or w.infobartype <= priority:
++                w.close()  # will be removed in the next event processing
+ 
+     @pyqtSlot(unicode, unicode)
+     def _showOutputOnInfoBar(self, msg, label):
+@@ -354,7 +349,6 @@ class RepoWidget(QWidget):
+ 
+         w = self.setInfoBar(qtlib.ConfirmInfoBar,
+                             _('Found incoming changesets'))
+-        assert w
+         w.acceptButton.setText(_('Accept'))
+         w.acceptButton.setToolTip(_('Pull incoming changesets into '
+                                     'your repository'))
+@@ -447,7 +441,6 @@ class RepoWidget(QWidget):
+ 
+         w = self.setInfoBar(qtlib.ConfirmInfoBar,
+                             _('%d outgoing changesets') % len(nodes))
+-        assert w
+         w.acceptButton.setText(_('Push'))
+         w.accepted.connect(self.push)  # TODO: to the same URL
+         w.rejected.connect(self.clearRevisionSet)
+# HG changeset patch
+# Parent d533e14e006b51188b723e2baef973cf5d568ba9
+diff --git a/tortoisehg/hgqt/qtlib.py b/tortoisehg/hgqt/qtlib.py
+--- a/tortoisehg/hgqt/qtlib.py
++++ b/tortoisehg/hgqt/qtlib.py
+@@ -780,7 +780,7 @@ class InfoBar(QFrame):
+         self.layout().addWidget(self._closebutton)
+ 
+     def addWidget(self, w):
+-        self.layout().insertWidget(self.layout().count() - 2, w)
++        self.layout().insertWidget(self.layout().count() - 2, w, stretch=1)
+ 
+     def addRightWidget(self, w):
+         self.layout().insertWidget(self.layout().count() - 1, w)
+@@ -794,8 +794,10 @@ class StatusInfoBar(InfoBar):
+     """Show status message"""
+     def __init__(self, message, parent=None):
+         super(StatusInfoBar, self).__init__(parent)
+-        self._msglabel = QLabel(message, self,
++        self._msglabel = QLabel(message, self, wordWrap=True,
+                                 textInteractionFlags=Qt.TextSelectableByMouse)
++        self._msglabel.setSizePolicy(QSizePolicy.Expanding,
++                                     QSizePolicy.Preferred)
+         self.addWidget(self._msglabel)
+ 
+ class CommandErrorInfoBar(InfoBar):
+@@ -805,8 +807,10 @@ class CommandErrorInfoBar(InfoBar):
+     def __init__(self, message, parent=None):
+         super(CommandErrorInfoBar, self).__init__(parent)
+ 
+-        self._msglabel = QLabel(message, self,
++        self._msglabel = QLabel(message, self, wordWrap=True,
+                                 textInteractionFlags=Qt.TextSelectableByMouse)
++        self._msglabel.setSizePolicy(QSizePolicy.Expanding,
++                                     QSizePolicy.Preferred)
+         self.addWidget(self._msglabel)
+ 
+         self._loglabel = QLabel('<a href="log:">%s</a>' % _('Show Log'))
+@@ -822,8 +826,10 @@ class ConfirmInfoBar(InfoBar):
+     def __init__(self, message, parent=None):
+         super(ConfirmInfoBar, self).__init__(parent)
+ 
+-        self._msglabel = QLabel(message, self,
++        self._msglabel = QLabel(message, self, wordWrap=True,
+                                 textInteractionFlags=Qt.TextSelectableByMouse)
++        self._msglabel.setSizePolicy(QSizePolicy.Expanding,
++                                     QSizePolicy.Preferred)
+         self.addWidget(self._msglabel)
+ 
+         self._buttons = QDialogButtonBox(self)
+# HG changeset patch
+# Parent 251c494a7924e70fbe14dd3d43d1751130080d23
+repowidget: clear infobar at start of sync operation (fixes #965)
+
+If we start new sync operation, the previous notification should be canceled.
+This patch adds syncStarted signal in order to know the start of sync, which
+is triggered by both repo widget (main toolbar) and sync widget.
+
+diff --git a/tortoisehg/hgqt/repowidget.py b/tortoisehg/hgqt/repowidget.py
+--- a/tortoisehg/hgqt/repowidget.py
++++ b/tortoisehg/hgqt/repowidget.py
+@@ -296,12 +296,16 @@ class RepoWidget(QWidget):
+         w.setFocus()  # to handle key press by InfoBar
+         return w
+ 
++    @pyqtSlot()
+     def clearInfoBar(self, priority=None):
+         """Close current infobar if available; return True if got empty"""
+         it = self._infobarlayout.itemAt(0)
+         if not it:
+             return True
+         if priority is None or it.widget().infobartype <= priority:
++            # removes current infobar explicitly, because close() seems to
++            # delay deletion until next eventloop.
++            self._infobarlayout.removeItem(it)
+             it.widget().close()
+             return True
+         else:
+@@ -363,6 +367,7 @@ class RepoWidget(QWidget):
+         sw.output.connect(self._showOutputOnInfoBar)
+         sw.progress.connect(self.progress)
+         sw.makeLogVisible.connect(self.makeLogVisible)
++        sw.syncStarted.connect(self.clearInfoBar)
+         sw.outgoingNodes.connect(self.setOutgoingNodes)
+         sw.showMessage.connect(self.showMessage)
+         sw.showMessage.connect(self._showMessageOnInfoBar)
+diff --git a/tortoisehg/hgqt/sync.py b/tortoisehg/hgqt/sync.py
+--- a/tortoisehg/hgqt/sync.py
++++ b/tortoisehg/hgqt/sync.py
+@@ -51,6 +51,7 @@ def parseurl(path):
+     return user, host, port, folder, passwd, scheme
+ 
+ class SyncWidget(QWidget, qtlib.TaskWidget):
++    syncStarted = pyqtSignal()  # incoming/outgoing/pull/push started
+     outgoingNodes = pyqtSignal(object)
+     incomingBundle = pyqtSignal(QString)
+     showMessage = pyqtSignal(unicode)
+@@ -630,6 +631,7 @@ class SyncWidget(QWidget, qtlib.TaskWidg
+         for b in self.opbuttons:
+             b.setEnabled(False)
+         self.stopAction.setEnabled(True)
++        self.syncStarted.emit()
+         if self.embedded:
+             self.showBusyIcon.emit('thg-sync')
+         else:
+# HG changeset patch
+# Parent 9b01fe93a30afbea5e5deb6a818b92e9c7a7b619
+diff --git a/tortoisehg/hgqt/repomodel.py b/tortoisehg/hgqt/repomodel.py
+--- a/tortoisehg/hgqt/repomodel.py
++++ b/tortoisehg/hgqt/repomodel.py
+@@ -406,7 +406,8 @@ class HgRepoListModel(QAbstractTableMode
+             return nullvariant
+         try:
+             return self.safedata(index, role)
+-        except Exception, e:
++        except error.LookupError, e:
++        #except Exception, e:
+             if role == Qt.DisplayRole:
+                 return QVariant(hglib.tounicode(str(e)))
+             else:

linestoprocess.diff

+# HG changeset patch
+# Parent 3ea676a4bfc5cf0c556462c7ab640dd7e62fa1f9
+
+diff --git a/tortoisehg/hgqt/fileview.py b/tortoisehg/hgqt/fileview.py
+--- a/tortoisehg/hgqt/fileview.py
++++ b/tortoisehg/hgqt/fileview.py
+@@ -490,23 +490,23 @@ class HgFileView(QFrame):
+             if self._fd:
+                 self._fd = None
+                 self._diffs = []
+-                self._linestoprocess = \
++                linestoprocess = \
+                     hglib.fromunicode(self.sci.text()).splitlines()
+-                self._firstlinetoprocess = 0
++                firstlinetoprocess = 0
+                 self._opcodes = True
+             # Process linesPerBlock lines at a time
+             linesPerBlock = 100
+             # Look for lines matching the "diff header"
+-            for n, line in enumerate(self._linestoprocess[:linesPerBlock]):
++            for n, line in enumerate(linestoprocess[:linesPerBlock]):
+                 if self.diffHeaderRegExp.match(line):
+-                    diffLine = self._firstlinetoprocess + n
++                    diffLine = firstlinetoprocess + n
+                     self._diffs.append([diffLine, diffLine])
+                     self.sci.markerAdd(diffLine, self.markerplus)
+-            self._linestoprocess = self._linestoprocess[linesPerBlock:]
+-            self._firstlinetoprocess += linesPerBlock
+-            if not self._linestoprocess:
++            linestoprocess = linestoprocess[linesPerBlock:]
++            firstlinetoprocess += linesPerBlock
++            if not linestoprocess:
+                 self._opcodes = False
+-                self._firstlinetoprocess = 0
++                firstlinetoprocess = 0
+         else:
+             if self._fd:
+                 olddata = self._fd.olddata.splitlines()

rebase-svn-unicode-try.diff

+# HG changeset patch
+# Parent 3cabbc71f95b14a6338718a9ece8fb8b96775d9a
+diff --git a/tortoisehg/hgqt/csinfo.py b/tortoisehg/hgqt/csinfo.py
+--- a/tortoisehg/hgqt/csinfo.py
++++ b/tortoisehg/hgqt/csinfo.py
+@@ -193,7 +193,7 @@ class SummaryInfo(object):
+                 return p4cl and ('changelist %s' % p4cl)
+             elif item == 'svn':
+                 extra = ctx.extra()
+-                cvt = extra.get('convert_revision', '')
++                cvt = hglib.tounicode(extra.get('convert_revision', ''))
+                 if cvt.startswith('svn:'):
+                     result = cvt.split('/', 1)[-1]
+                     if cvt != result:
+@@ -207,6 +207,7 @@ class SummaryInfo(object):
+             raise UnknownItem(item)
+         if 'data' in custom and not kargs.get('usepreset', False):
+             try:
++                print [widget, item, ctx]
+                 return custom['data'](widget, item, ctx)
+             except UnknownItem:
+                 pass
+@@ -250,7 +251,7 @@ class SummaryInfo(object):
+             elif item in ('revid', 'transplant'):
+                 return qtlib.markup(value, **mono)
+             elif item in ('revnum', 'p4', 'svn', 'close'):
+-                return str(value)
++                return unicode(value)
+             elif item in ('rawbranch', 'branch'):
+                 opts = dict(fg='black', bg='#aaffaa')
+                 return qtlib.markup(' %s ' % value, **opts)
+@@ -411,6 +412,7 @@ class SummaryPanel(SummaryBase, QWidget)
+             label = qtlib.markup(self.get_label(item), weight='bold')
+             if isinstance(markups, basestring):
+                 markups = [markups,]
++            print repr(label), repr(markups[0])
+             buf += PANEL_TMPL % (label, markups.pop(0))
+             for markup in markups:
+                 buf += PANEL_TMPL % ('&nbsp;', markup)
+diff --git a/tortoisehg/hgqt/revpanel.py b/tortoisehg/hgqt/revpanel.py
+--- a/tortoisehg/hgqt/revpanel.py
++++ b/tortoisehg/hgqt/revpanel.py
+@@ -72,6 +72,8 @@ def data_func(widget, item, ctx):
+         ts = widget.get_data(item, usepreset=True)
+         if not ts:
+             return None
++        if item == 'svn':
++            return ts  # XXX
+         try:
+             tctx = ctx._repo[ts]
+             return revline_data(tctx)

repochange-delay.diff

+# HG changeset patch
+# Date 1307890904 -32400
+# User Yuya Nishihara <yuya@tcha.org>
+# Parent 4ec9f5f37547d1de733923e9fc74b8b0fb17190c
+thgrepo: wait 100msec before emitting repositoryChanged signal
+
+Because MQ saves its state file *after* unlocking repo, the repository
+content can be inconsistent immediately after unlocking.
+
+diff --git a/tortoisehg/hgqt/thgrepo.py b/tortoisehg/hgqt/thgrepo.py
+--- a/tortoisehg/hgqt/thgrepo.py
++++ b/tortoisehg/hgqt/thgrepo.py
+@@ -78,6 +78,13 @@ class ThgRepoWrapper(QObject):
+         repo.workingDirectoryChanged = self.workingDirectoryChanged
+         repo.workingBranchChanged = self.workingBranchChanged
+         self.recordState()
++
++        # slight delay needed to wait completion of post-unlock process.
++        # e.g. MQ saves patch state after unlocking repo.
++        self._emitrepochangedtimer = QTimer(self, singleShot=True,
++                                            interval=100)
++        self._emitrepochangedtimer.timeout.connect(self._emitrepochanged)
++
+         if isinstance(repo, bundlerepo.bundlerepository):
+             dbgoutput('not watching F/S events for bundle repository')
+         else:
+@@ -191,7 +198,7 @@ class ThgRepoWrapper(QObject):
+                 return
+             self.recordState()
+             self.repo.thginvalidate()
+-            self.repositoryChanged.emit()
++            self._emitrepochangedtimer.start()
+ 
+     def _checkdirstate(self):
+         'Check for new dirstate mtime, then working parent changes'
+@@ -210,7 +217,7 @@ class ThgRepoWrapper(QObject):
+                 return True
+             self.recordState()
+             self.repo.thginvalidate()
+-            self.repositoryChanged.emit()
++            self._emitrepochangedtimer.start()
+             return True
+         try:
+             mtime = os.path.getmtime(self.repo.join('branch'))
+@@ -234,6 +241,15 @@ class ThgRepoWrapper(QObject):
+             return True
+         return False
+ 
++    @pyqtSlot()
++    def _emitrepochanged(self):
++        if self.locked():
++            dbgoutput('lock still held - delays emission')
++            self._emitrepochangedtimer.start()
++            return
++        dbgoutput('emit repository changed')
++        self.repositoryChanged.emit()
++
+     def _checkuimtime(self):
+         'Check for modified config files, or a new .hg/hgrc file'
+         try:

repoview-selecte.diff

+# HG changeset patch
+# Parent ebc688d14817f5fa0fa9da014929d813a557096e
+diff --git a/tortoisehg/hgqt/repoview.py b/tortoisehg/hgqt/repoview.py
+--- a/tortoisehg/hgqt/repoview.py
++++ b/tortoisehg/hgqt/repoview.py
+@@ -215,13 +215,15 @@ class HgRepoView(QTableView):
+ 
+     def onRowChange(self, index, index_from):
+         rev = self.revFromindex(index)
+-        if self.current_rev != rev and not self._in_history:
++        changed = self.current_rev != rev
++        if changed and not self._in_history:
+             del self._rev_history[self._rev_pos+1:]
+             self._rev_history.append(rev)
+             self._rev_pos = len(self._rev_history)-1
+         self._in_history = False
+         self.current_rev = rev
+-        self.revisionSelected.emit(rev)
++        if changed:
++            self.revisionSelected.emit(rev)
+ 
+     def selectedRevisions(self):
+         """Return the list of selected revisions"""
-trying-open-in-new-window.diff #+experimental
-break-qtlib.diff #+debug
-cmdui-delete-debug.diff #+debug
-workbench-drop-return.diff #+experimental
-logwidget-truncate.diff #+experimental
-debug-gc.diff #+debug
-threadui-prompt.diff #+experimental
-thread-interact.diff #+experimental
-cmddialog-debug.diff #+debug
-infinite-exception.diff #+experimental
-blackholer.diff #+debug
-fontsetting-visible.diff #+experimental
-commandrunner-test.diff #+tests
-cmdui-debug.diff #+debug
+infobar-clicked.diff
+issue965.diff
+repoview-selecte.diff
+rebase-svn-unicode-try.diff
+svnrev-uni.diff
+elidelab.diff
+infobar.diff
+linestoprocess.diff
+repochange-delay.diff
+lesscatch.diff
+infobar-stacked.diff
+filedata-dbg.diff
+trying-open-in-new-window.diff
+break-qtlib.diff
+cmdui-delete-debug.diff
+workbench-drop-return.diff
+logwidget-truncate.diff
+debug-gc.diff
+threadui-prompt.diff
+thread-interact.diff
+cmddialog-debug.diff
+infinite-exception.diff
+blackholer.diff
+fontsetting-visible.diff
+commandrunner-test.diff
+cmdui-debug.diff
 errorinfobar.diff
 repoview-header.diff
 repoview-height.diff
 workbench-hidestatusbar.diff
-flashmsg.diff
 init-complete.diff
 destroy-tasktab-on-switch.diff
 losslesslocalstr.diff
+# HG changeset patch
+# Parent d78d17ef5fddd6514dce27993547f534eac98522
+diff --git a/tortoisehg/hgqt/csinfo.py b/tortoisehg/hgqt/csinfo.py
+--- a/tortoisehg/hgqt/csinfo.py
++++ b/tortoisehg/hgqt/csinfo.py
+@@ -193,7 +193,7 @@ class SummaryInfo(object):
+                 return p4cl and ('changelist %s' % p4cl)
+             elif item == 'svn':
+                 extra = ctx.extra()
+-                cvt = extra.get('convert_revision', '')
++                cvt = hglib.tounicode(extra.get('convert_revision', ''))
+                 if cvt.startswith('svn:'):
+                     result = cvt.split('/', 1)[-1]
+                     if cvt != result:
+diff --git a/tortoisehg/hgqt/revpanel.py b/tortoisehg/hgqt/revpanel.py
+--- a/tortoisehg/hgqt/revpanel.py
++++ b/tortoisehg/hgqt/revpanel.py
+@@ -73,7 +73,7 @@ def data_func(widget, item, ctx):
+         if not ts:
+             return None
+         try:
+-            tctx = ctx._repo[ts]
++            tctx = ctx._repo[hglib.fromunicode(ts)]
+             return revline_data(tctx)
+         except (error.LookupError, error.RepoLookupError, error.RepoError):
+             return ts