# HG changeset patch
# User Alain Leufroy <alain@leufroy.fr>
# Date 1369786110 -7200
# Wed May 29 02:08:30 2013 +0200
# Node ID a24bedbce41bf4b4169f0a19e2dda60d07073a98
# Parent e54a7775ff7b775ca7166eb9af66defc14570914
[qt4] use new signal coding-style
The new API use the more intuitive ``signal.emit(arg)`` instead of
``emit(signal, arg)`` (also apply to other signal related method like
``connect``.
related to #137588
# User Alain Leufroy <alain@leufroy.fr>
# Date 1369786110 -7200
# Wed May 29 02:08:30 2013 +0200
# Node ID a24bedbce41bf4b4169f0a19e2dda60d07073a98
# Parent e54a7775ff7b775ca7166eb9af66defc14570914
[qt4] use new signal coding-style
The new API use the more intuitive ``signal.emit(arg)`` instead of
``emit(signal, arg)`` (also apply to other signal related method like
``connect``.
related to #137588
@@ -50,13 +50,10 @@
1 2 # load icons from resource and store them in a dict, no matter their 3 # extension (.svg or .png) 4 from PyQt4 import QtCore 5 from PyQt4 import QtGui, uic 6 -connect = QtCore.QObject.connect 7 -SIGNAL = QtCore.SIGNAL 8 -Qt = QtCore.Qt 9 import hgqv_rc 10 11 12 _icons = {} 13 def _load_icons():
@@ -16,23 +16,29 @@
14 15 """ 16 Qt4 widgets to display diffs as blocks 17 """ 18 import sys, os 19 +from functools import partial 20 21 from PyQt4 import QtGui, QtCore 22 -from PyQt4.QtCore import Qt, SIGNAL 23 +from PyQt4.QtCore import Qt, pyqtSignal 24 25 class BlockList(QtGui.QWidget): 26 """ 27 A simple widget to be 'linked' to the scrollbar of a diff text 28 view. 29 30 It represents diff blocks with colored rectangles, showing 31 currently viewed area by a semi-transparant rectangle sliding 32 above them. 33 """ 34 + 35 + value_changed = pyqtSignal(int) 36 + range_changed = pyqtSignal(int, int) 37 + page_step_changed = pyqtSignal(int) 38 + 39 def __init__(self, *args): 40 QtGui.QWidget.__init__(self, *args) 41 self._blocks = set() 42 self._minimum = 0 43 self._maximum = 100
@@ -55,37 +61,34 @@
44 self._blocks.add((typ, alo, ahi)) 45 46 def setMaximum(self, maximum): 47 self._maximum = maximum 48 self.update() 49 - self.emit(SIGNAL('rangeChanged(int, int)'), 50 - self._minimum, self._maximum) 51 + self.range_changed[int, int].emit(self._minimum, self._maximum) 52 53 def setMinimum(self, minimum): 54 self._minimum = minimum 55 self.update() 56 - self.emit(SIGNAL('rangeChanged(int, int)'), 57 - self._minimum, self._maximum) 58 + self.range_changed[int, int].emit(self._minimum, self._maximum) 59 60 def setRange(self, minimum, maximum): 61 self._minimum = minimum 62 self._maximum = maximum 63 self.update() 64 - self.emit(SIGNAL('rangeChanged(int, int)'), 65 - self._minimum, self._maximum) 66 + self.range_changed[int, int].emit(self._minimum, self._maximum) 67 68 def setValue(self, val): 69 if val != self._value: 70 self._value = val 71 self.update() 72 - self.emit(SIGNAL('valueChanged(int)'), val) 73 + self.value_changed[int].emit(val) 74 75 def setPageStep(self, pagestep): 76 if pagestep != self._pagestep: 77 self._pagestep = pagestep 78 self.update() 79 - self.emit(SIGNAL('pageStepChanged(int)'), pagestep) 80 + self.page_step_changed[int].emit(pagestep) 81 82 def linkScrollBar(self, sbar): 83 """ 84 Make the block list displayer be linked to the scrollbar 85 """
@@ -94,15 +97,17 @@
86 self.setMaximum(sbar.maximum()) 87 self.setMinimum(sbar.minimum()) 88 self.setPageStep(sbar.pageStep()) 89 self.setValue(sbar.value()) 90 self.setUpdatesEnabled(True) 91 - self.connect(sbar, SIGNAL('valueChanged(int)'), self.setValue) 92 - self.connect(sbar, SIGNAL('rangeChanged(int, int)'), self.setRange) 93 - self.connect(self, SIGNAL('valueChanged(int)'), sbar.setValue) 94 - self.connect(self, SIGNAL('rangeChanged(int, int)'), sbar.setRange) 95 - self.connect(self, SIGNAL('pageStepChanged(int)'), sbar.setPageStep) 96 + sbar.valueChanged[int].connect(self.setValue) 97 + sbar.rangeChanged[int, int].connect(self.setRange) 98 + # use partial to bypass the slot overload checking that fails with 99 + # pyqt4 4.10.1 on debian 100 + self.value_changed[int].connect(partial(sbar.setValue)) 101 + self.range_changed[int, int].connect(partial(sbar.setRange)) 102 + self.page_step_changed[int].connect(partial(sbar.setPageStep)) 103 104 def syncPageStep(self): 105 self.setPageStep(self._sbar.pageStep()) 106 107 def paintEvent(self, event):
@@ -129,10 +134,15 @@
108 displaying 2 versions of a same file (diff). 109 110 It will show graphically matching diff blocks between the 2 text 111 areas. 112 """ 113 + 114 + value_changed = pyqtSignal([int], [int, str]) 115 + range_changed = pyqtSignal([int, int], [int, int, str]) 116 + page_step_changed = pyqtSignal([int], [int, str]) 117 + 118 def __init__(self, *args): 119 QtGui.QWidget.__init__(self, *args) 120 self._blocks = set() 121 self._minimum = {'left': 0, 'right': 0} 122 self._maximum = {'left': 100, 'right': 100}
@@ -238,17 +248,17 @@
123 p.restore() 124 125 def setMaximum(self, maximum, side): 126 self._maximum[side] = maximum 127 self.update() 128 - self.emit(SIGNAL('rangeChanged(int, int, const QString &)'), 129 + self.range_changed[int, int, str].emit( 130 self._minimum[side], self._maximum[side], side) 131 132 def setMinimum(self, minimum, side): 133 self._minimum[side] = minimum 134 self.update() 135 - self.emit(SIGNAL('rangeChanged(int, int, const QString &)'), 136 + self.range_changed[int, int, str].emit( 137 self._minimum[side], self._maximum[side], side) 138 139 def setRange(self, minimum, maximum, side=None): 140 if side is None: 141 if self.sender() == self._sbar['left']:
@@ -256,11 +266,11 @@
142 else: 143 side = 'right' 144 self._minimum[side] = minimum 145 self._maximum[side] = maximum 146 self.update() 147 - self.emit(SIGNAL('rangeChanged(int, int, const QString &)'), 148 + self.range_changed[int, int, str].emit( 149 self._minimum[side], self._maximum[side], side) 150 151 def setValue(self, val, side=None): 152 if side is None: 153 if self.sender() == self._sbar['left']:
@@ -268,18 +278,17 @@
154 else: 155 side = 'right' 156 if val != self._value[side]: 157 self._value[side] = val 158 self.update() 159 - self.emit(SIGNAL('valueChanged(int, const QString &)'), val, side) 160 + self.value_changed[int, str].emit(val, side) 161 162 def setPageStep(self, pagestep, side): 163 if pagestep != self._pagestep[side]: 164 self._pagestep[side] = pagestep 165 self.update() 166 - self.emit(SIGNAL('pageStepChanged(int, const QString &)'), 167 - pagestep, side) 168 + self.page_step_changed[int, str].emit(pagestep, side) 169 170 def syncPageStep(self): 171 for side in ['left', 'right']: 172 self.setPageStep(self._sbar[side].pageStep(), side) 173
@@ -297,14 +306,14 @@
174 self.setMaximum(sb.maximum(), side) 175 self.setMinimum(sb.minimum(), side) 176 self.setPageStep(sb.pageStep(), side) 177 self.setValue(sb.value(), side) 178 self.setUpdatesEnabled(True) 179 - self.connect(sb, SIGNAL('valueChanged(int)'), self.setValue) 180 - self.connect(sb, SIGNAL('rangeChanged(int, int)'), self.setRange) 181 + sb.valueChanged[int].connect(self.setValue) 182 + sb.rangeChanged[int, int].connect(self.setRange) 183 184 - self.connect(self, SIGNAL('valueChanged(int, const QString &)'), 185 + self.value_changed[int, str].connect( 186 lambda v, s: side==s and sb.setValue(v)) 187 - self.connect(self, SIGNAL('rangeChanged(int, int, const QString )'), 188 + self.range_changed[int, int, str].connect( 189 lambda v1, v2, s: side==s and sb.setRange(v1, v2)) 190 - self.connect(self, SIGNAL('pageStepChanged(int, const QString )'), 191 + self.page_step_changed[int, str].connect( 192 lambda v, s: side==s and sb.setPageStep(v))
@@ -17,12 +17,10 @@
193 from hgviewlib.qt4.hgdialogmixin import HgDialogMixin 194 from hgviewlib.hgviewhelp import help_msg, get_options_helpmsg 195 196 Qt = QtCore.Qt 197 bold = QtGui.QFont.Bold 198 -connect = QtCore.QObject.connect 199 -SIGNAL = QtCore.SIGNAL 200 201 try: 202 from docutils.core import publish_string 203 except: 204 def publish_string(s, *args, **kwargs):
@@ -21,12 +21,10 @@
205 import os.path as osp 206 import sys 207 208 from PyQt4 import QtCore 209 from PyQt4 import QtGui, uic 210 -connect = QtCore.QObject.connect 211 -SIGNAL = QtCore.SIGNAL 212 Qt = QtCore.Qt 213 214 from hgviewlib.config import HgConfig 215 from hgviewlib.qt4 import should_rebuild 216
@@ -74,22 +72,19 @@
217 # we explicitly create a QShortcut so we can disable it 218 # when a "helper context toolbar" is activated (which can be 219 # closed hitting the Esc shortcut) 220 self.esc_shortcut = QtGui.QShortcut(self) 221 self.esc_shortcut.setKey(Qt.Key_Escape) 222 - connect(self.esc_shortcut, SIGNAL('activated()'), 223 - self.maybeClose) 224 + self.esc_shortcut.activated.connect(self.maybeClose) 225 self._quickbars = [] 226 227 def attachQuickBar(self, qbar): 228 qbar.setParent(self) 229 self._quickbars.append(qbar) 230 - connect(qbar, SIGNAL('escShortcutDisabled(bool)'), 231 - self.setShortcutsEnabled) 232 + qbar.esc_shortcut_disabled[bool].connect(self.setShortcutsEnabled) 233 self.addToolBar(Qt.BottomToolBarArea, qbar) 234 - connect(qbar, SIGNAL('visible'), 235 - self.ensureOneQuickBar) 236 + qbar.unhidden.connect(self.ensureOneQuickBar) 237 238 def setShortcutsEnabled(self, enabled=True): 239 for sh in self.disab_shortcuts: 240 sh.setEnabled(enabled) 241
@@ -23,11 +23,11 @@
242 import difflib 243 244 from mercurial import ui, hg, util 245 246 from PyQt4 import QtGui, QtCore, Qsci 247 -from PyQt4.QtCore import Qt 248 +from PyQt4.QtCore import Qt, pyqtSignal 249 250 from hgviewlib.application import (FileViewer as _FileViewer, 251 FileDiffViewer as _FileDiffViewer) 252 from hgviewlib.util import tounicode, rootpath 253
@@ -36,13 +36,10 @@
254 from hgviewlib.qt4.hgrepomodel import FileRevModel 255 from hgviewlib.qt4.blockmatcher import BlockList, BlockMatch 256 from hgviewlib.qt4.lexers import get_lexer 257 from hgviewlib.qt4.quickbar import FindInGraphlogQuickBar 258 259 -connect = QtCore.QObject.connect 260 -disconnect = QtCore.QObject.disconnect 261 -SIGNAL = QtCore.SIGNAL 262 263 sides = ('left', 'right') 264 otherside = {'left': 'right', 'right': 'left'} 265 266
@@ -65,12 +62,11 @@
267 self.setupModels() 268 269 def setRepoViewer(self, repoviewer=None): 270 self.repoviewer = repoviewer 271 if repoviewer: 272 - connect(repoviewer, SIGNAL('finished(int)'), 273 - lambda x: self.setRepoViewer()) 274 + repoviewer.destroyed.connect(lambda x: self.setRepoViewer()) 275 276 def reload(self): 277 self.repo = util.build_repo(self.repo.ui, self.repo.root) 278 self.setupModels() 279
@@ -87,12 +83,11 @@
280 lexer.setDefaultFont(self._font) 281 lexer.setFont(self._font) 282 self.lexer = lexer 283 284 def modelFilled(self): 285 - disconnect(self.filerevmodel, SIGNAL('filled'), 286 - self.modelFilled) 287 + self.filerevmodel.filled.disconnect(self.modelFilled) 288 if isinstance(self._show_rev, int): 289 index = self.filerevmodel.indexFromRev(self._show_rev) 290 self._show_rev = None 291 else: 292 index = self.filerevmodel.index(0,0)
@@ -118,20 +113,20 @@
293 _uifile = 'fileviewer.ui' 294 295 def setupViews(self): 296 self.textView.setFont(self._font) 297 self.setWindowTitle('hgview filelog: %s' % os.path.abspath(self.filename)) 298 - connect(self.textView, SIGNAL('showMessage'), 299 - self.statusBar().showMessage) 300 + self.textView.message_logged.connect(self.statusBar().showMessage) 301 302 def setupToolbars(self): 303 self.find_toolbar = FindInGraphlogQuickBar(self) 304 self.find_toolbar.attachFileView(self.textView) 305 - connect(self.find_toolbar, SIGNAL('revisionSelected'), 306 - self.tableView_revisions.goto) 307 - connect(self.find_toolbar, SIGNAL('showMessage'), 308 - self.statusBar().showMessage) 309 + self.find_toolbar.revision_selected.connect( 310 + self.tableView_revisions.goto) 311 + self.find_toolbar.revision_selected[int].connect( 312 + self.tableView_revisions.goto) 313 + self.find_toolbar.message_logged.connect(self.statusBar().showMessage) 314 self.attachQuickBar(self.find_toolbar) 315 316 self.toolBar_edit.addSeparator() 317 self.toolBar_edit.addAction(self.tableView_revisions._actions['back']) 318 self.toolBar_edit.addAction(self.tableView_revisions._actions['forward'])
@@ -144,63 +139,58 @@
319 self.attachQuickBar(self.tableView_revisions.goto_toolbar) 320 321 def setupModels(self): 322 self.filerevmodel = FileRevModel(self.repo) 323 self.tableView_revisions.setModel(self.filerevmodel) 324 - connect(self.tableView_revisions, 325 - SIGNAL('revisionSelected'), 326 - self.revisionSelected) 327 - connect(self.tableView_revisions, 328 - SIGNAL('revisionActivated'), 329 + self.tableView_revisions.revision_selected.connect( 330 + self.revisionSelected) 331 + self.tableView_revisions.revision_selected[int].connect( 332 + self.revisionSelected) 333 + self.tableView_revisions.revision_activated.connect( 334 self.revisionActivated) 335 - connect(self.filerevmodel, SIGNAL('showMessage'), 336 - self.statusBar().showMessage, 337 - Qt.QueuedConnection) 338 - connect(self.filerevmodel, QtCore.SIGNAL('filled'), 339 - self.modelFilled) 340 + self.tableView_revisions.revision_activated[int].connect( 341 + self.revisionActivated) 342 + self.filerevmodel.message_logged.connect( 343 + self.statusBar().showMessage, 344 + Qt.QueuedConnection) 345 + self.filerevmodel.filled.connect(self.modelFilled) 346 self.textView.setMode('file') 347 self.textView.setModel(self.filerevmodel) 348 self.find_toolbar.setModel(self.filerevmodel) 349 self.find_toolbar.setFilterFiles([self.filename]) 350 self.find_toolbar.setMode('file') 351 self.filerevmodel.setFilename(self.filename) 352 353 def createActions(self): 354 - connect(self.actionClose, SIGNAL('triggered()'), 355 - self.close) 356 - connect(self.actionReload, SIGNAL('triggered()'), 357 - self.reload) 358 + self.actionClose.triggered.connect(self.close) 359 + self.actionReload.triggered.connect(self.reload) 360 self.actionClose.setIcon(geticon('quit')) 361 self.actionReload.setIcon(geticon('reload')) 362 363 self.actionDiffMode = QtGui.QAction('Diff mode', self) 364 self.actionDiffMode.setCheckable(True) 365 - connect(self.actionDiffMode, SIGNAL('toggled(bool)'), 366 - self.setMode) 367 + self.actionDiffMode.toggled[bool].connect(self.setMode) 368 369 self.actionAnnMode = QtGui.QAction('Annotate', self) 370 self.actionAnnMode.setCheckable(True) 371 - connect(self.actionAnnMode, SIGNAL('toggled(bool)'), 372 - self.textView.setAnnotate) 373 + self.actionAnnMode.toggled[bool].connect(self.textView.setAnnotate) 374 375 self.actionNextDiff = QtGui.QAction(geticon('down'), 'Next diff', self) 376 self.actionNextDiff.setShortcut('Alt+Down') 377 self.actionPrevDiff = QtGui.QAction(geticon('up'), 'Previous diff', self) 378 self.actionPrevDiff.setShortcut('Alt+Up') 379 - connect(self.actionNextDiff, SIGNAL('triggered()'), 380 - self.nextDiff) 381 - connect(self.actionPrevDiff, SIGNAL('triggered()'), 382 - self.prevDiff) 383 + self.actionNextDifftriggered.connect(self.nextDiff) 384 + self.actionPrevDiff.triggered.connect(self.prevDiff) 385 386 def revisionSelected(self, rev): 387 pos = self.textView.verticalScrollBar().value() 388 ctx = self.filerevmodel.repo.changectx(rev) 389 self.textView.setContext(ctx) 390 self.textView.displayFile(self.filerevmodel.graph.filename(rev)) 391 self.textView.verticalScrollBar().setValue(pos) 392 self.actionPrevDiff.setEnabled(False) 393 - connect(self.textView, SIGNAL('filled'), 394 + self.textView.filled.connect( 395 lambda self=self: self.actionNextDiff.setEnabled(self.textView.fileMode() and self.textView.nDiffs())) 396 397 def goto(self, rev): 398 index = self.filerevmodel.indexFromRev(rev) 399 if index is not None:
@@ -229,10 +219,12 @@
400 """ 401 Qt4 dialog to display diffs between different mercurial revisions of a file. 402 """ 403 _uifile = 'filediffviewer.ui' 404 405 + diff_filled = pyqtSignal() 406 + 407 def setupViews(self): 408 self.tableView_revisions = self.tableView_revisions_left 409 self.tableViews = {'left': self.tableView_revisions_left, 410 'right': self.tableView_revisions_right} 411 # viewers are Scintilla editors
@@ -287,64 +279,58 @@
412 413 for side in sides: 414 table = getattr(self, 'tableView_revisions_%s' % side) 415 table.setTabKeyNavigation(False) 416 #table.installEventFilter(self) 417 - connect(table, SIGNAL('revisionSelected'), self.revisionSelected) 418 - connect(table, SIGNAL('revisionActivated'), self.revisionActivated) 419 + table.revision_selected.connect(self.revisionSelected) 420 + table.revision_selected[int].connect(self.revisionSelected) 421 + table.revision_activated.connect(self.revisionActivated) 422 + table.revision_activated[int].connect(self.revisionActivated) 423 424 - connect(self.viewers[side].verticalScrollBar(), 425 - QtCore.SIGNAL('valueChanged(int)'), 426 + self.viewers[side].verticalScrollBar().valueChanged[int].connect( 427 lambda value, side=side: self.vbar_changed(value, side)) 428 self.attachQuickBar(table.goto_toolbar) 429 430 self.setTabOrder(table, self.viewers['left']) 431 self.setTabOrder(self.viewers['left'], self.viewers['right']) 432 self.setWindowTitle('hgview diff: %s' % os.path.abspath(self.filename)) 433 434 # timer used to fill viewers with diff block markers during GUI idle time 435 self.timer = QtCore.QTimer() 436 self.timer.setSingleShot(False) 437 - connect(self.timer, SIGNAL("timeout()"), 438 - self.idle_fill_files) 439 + self.timer.timeout.connect(self.idle_fill_files) 440 441 def setupModels(self): 442 self.filedata = {'left': None, 'right': None} 443 self._invbarchanged = False 444 self.filerevmodel = FileRevModel(self.repo, self.filename) 445 - connect(self.filerevmodel, QtCore.SIGNAL('filled'), 446 - self.modelFilled) 447 + self.filerevmodel.filled.connect(self.modelFilled) 448 self.tableView_revisions_left.setModel(self.filerevmodel) 449 self.tableView_revisions_right.setModel(self.filerevmodel) 450 451 def createActions(self): 452 - connect(self.actionClose, SIGNAL('triggered()'), 453 - self.close) 454 - connect(self.actionReload, SIGNAL('triggered()'), 455 - self.reload) 456 + self.actionClose.triggered.connect(self.close) 457 + self.actionReload.triggered.connect(self.reload) 458 self.actionClose.setIcon(geticon('quit')) 459 self.actionReload.setIcon(geticon('reload')) 460 461 self.actionNextDiff = QtGui.QAction(geticon('down'), 'Next diff', self) 462 self.actionNextDiff.setShortcut('Alt+Down') 463 self.actionPrevDiff = QtGui.QAction(geticon('up'), 'Previous diff', self) 464 self.actionPrevDiff.setShortcut('Alt+Up') 465 - connect(self.actionNextDiff, SIGNAL('triggered()'), 466 - self.nextDiff) 467 - connect(self.actionPrevDiff, SIGNAL('triggered()'), 468 - self.prevDiff) 469 + self.actionNextDiff.triggered.connect(self.nextDiff) 470 + self.actionPrevDiff.triggered.connect(self.prevDiff) 471 self.actionNextDiff.setEnabled(False) 472 self.actionPrevDiff.setEnabled(False) 473 474 def setupToolbars(self): 475 self.toolBar_edit.addSeparator() 476 self.toolBar_edit.addAction(self.actionNextDiff) 477 self.toolBar_edit.addAction(self.actionPrevDiff) 478 479 def modelFilled(self): 480 - disconnect(self.filerevmodel, SIGNAL('filled'), 481 - self.modelFilled) 482 + self.filerevmodel.filled.disconnect(self.modelFilled) 483 if self._show_rev is not None: 484 rev = self._show_rev 485 self._show_rev = None 486 else: 487 rev = self.filerevmodel.graph[0].rev
@@ -402,11 +388,11 @@
488 for n in range(30): # burst pool 489 if self._diff is None or not self._diff.get_opcodes(): 490 self._diff = None 491 self.timer.stop() 492 self.setDiffNavActions(-1) 493 - self.emit(SIGNAL('diffFilled')) 494 + self.diff_filled.emit() 495 break 496 497 tag, alo, ahi, blo, bhi = self._diff.get_opcodes().pop(0) 498 499 w = self.viewers['left']
@@ -24,13 +24,12 @@
500 from mercurial.error import LookupError 501 except ImportError: 502 from mercurial.revlog import LookupError 503 504 from PyQt4 import QtCore, QtGui, Qsci 505 +from PyQt4.QtCore import pyqtSignal 506 Qt = QtCore.Qt 507 -connect = QtCore.QObject.connect 508 -SIGNAL = QtCore.SIGNAL 509 510 from hgviewlib.decorators import timeit 511 from hgviewlib.util import exec_flag_changed, isbfile, bfilepath, tounicode 512 from hgviewlib.config import HgConfig 513
@@ -73,12 +72,11 @@
514 marker = self.markerDefine(qsci.Background) 515 color = 0x7FFF00 + (i-N/2)*256/N*256*256 - i*256/N*256 + i*256/N 516 self.SendScintilla(qsci.SCI_MARKERSETBACK, marker, color) 517 self.markers.append(marker) 518 519 - connect(textarea.verticalScrollBar(), 520 - SIGNAL('valueChanged(int)'), 521 + textarea.verticalScrollBar().valueChanged[int].connect( 522 self.verticalScrollBar().setValue) 523 524 def setFilectx(self, fctx): 525 self.fctx = fctx 526 ann = [f.rev() for f, line in fctx.annotate(follow=True)]
@@ -123,11 +121,11 @@
527 if tip: 528 act.setStatusTip(tip) 529 if key: 530 act.setShortcut(key) 531 if cb: 532 - connect(act, SIGNAL('triggered()'), cb) 533 + act.triggered.connect(cb) 534 self._actions[name] = act 535 self.addAction(act) 536 self._actions['diffmode'].setCheckable(True) 537 self._actions['annmode'].setCheckable(True) 538 self._actions['show-big-file'].setCheckable(True)
@@ -142,10 +140,14 @@
539 menu.addSeparator() 540 menu.exec_(event.globalPos()) 541 542 543 class HgFileView(QtGui.QFrame): 544 + 545 + message_logged = pyqtSignal(str, int) 546 + rev_for_diff_changed = pyqtSignal(int) 547 + 548 def __init__(self, parent=None): 549 QtGui.QFrame.__init__(self, parent) 550 framelayout = QtGui.QVBoxLayout(self) 551 framelayout.setContentsMargins(0,0,0,0) 552 framelayout.setSpacing(0)
@@ -231,22 +233,16 @@
553 self._mode = "diff" # can be 'diff' or 'file' 554 self.filedata = None 555 556 self.timer = QtCore.QTimer() 557 self.timer.setSingleShot(False) 558 - self.connect(self.timer, QtCore.SIGNAL("timeout()"), 559 - self.idle_fill_files) 560 - self.connect(self.sci._actions['diffmode'], SIGNAL('toggled(bool)'), 561 - self.setMode) 562 - self.connect(self.sci._actions['annmode'], SIGNAL('toggled(bool)'), 563 - self.setAnnotate) 564 - self.connect(self.sci._actions['prev'], SIGNAL('triggered()'), 565 - self.prevDiff) 566 - self.connect(self.sci._actions['next'], SIGNAL('triggered()'), 567 - self.nextDiff) 568 - self.connect(self.sci._actions['show-big-file'], SIGNAL('toggled(bool)'), 569 - self.showBigFile) 570 + self.timer.timeout.connect(self.idle_fill_files) 571 + self.sci._actions['diffmode'].toggled[bool].connect(self.setMode) 572 + self.sci._actions['annmode'].toggled[bool].connect(self.setAnnotate) 573 + self.sci._actions['prev'].triggered.connect(self.prevDiff) 574 + self.sci._actions['next'].triggered.connect(self.nextDiff) 575 + self.sci._actions['show-big-file'].toggled[bool].connect(self.showBigFile) 576 self.sci._actions['diffmode'].setChecked(True) 577 578 def resizeEvent(self, event): 579 QtGui.QFrame.resizeEvent(self, event) 580 h = self.sci.horizontalScrollBar().height()
@@ -321,11 +317,11 @@
581 else: 582 self._filename = filename 583 584 if rev is not None: 585 self._p_rev = rev 586 - self.emit(SIGNAL('revForDiffChanged'), rev) 587 + self.rev_for_diff_changed.emit(rev) 588 self.sci.clear() 589 self.ann.clear() 590 self.filenamelabel.setText(" ") 591 self.execflaglabel.clear() 592 if filename is None:
@@ -510,13 +506,13 @@
593 n = len(text) 594 while pos[-1] > -1: 595 self.sci.SendScintilla(qsci.SCI_INDICATORFILLRANGE, pos[-1], n) 596 pos.append(data.find(text, pos[-1]+1)) 597 pos = [x for x in pos if x > -1] 598 - self.emit(SIGNAL('showMessage'), 599 - "Found %d occurrences of '%s' in current file or diff" % (len(pos), text), 600 - 2000) 601 + self.message_logged.emit( 602 + u"Found %d occurrences of '%s' in current file or diff" % (len(pos), tounicode(text)), 603 + 2000) 604 return pos 605 606 def highlightCurrentSearchString(self, pos, text): 607 line = self.sci.SendScintilla(qsci.SCI_LINEFROMPOSITION, pos) 608 #line, idx = w.lineIndexFromPosition(nextpos)
@@ -576,10 +572,13 @@
609 610 class HgFileListView(QtGui.QTableView): 611 """ 612 A QTableView for displaying a HgFileListModel 613 """ 614 + 615 + file_selected = pyqtSignal([str, int], [str]) 616 + 617 def __init__(self, parent=None): 618 QtGui.QTableView.__init__(self, parent) 619 self.setShowGrid(False) 620 self.verticalHeader().hide() 621 self.verticalHeader().setDefaultSectionSize(20)
@@ -590,28 +589,23 @@
622 623 self.horizontalHeader().setToolTip('Double click to toggle merge mode') 624 625 self.createActions() 626 627 - connect(self.horizontalHeader(), SIGNAL('sectionDoubleClicked(int)'), 628 + self.horizontalHeader().sectionDoubleClicked[int].connect( 629 self.toggleFullFileList) 630 - connect(self, 631 - SIGNAL('doubleClicked (const QModelIndex &)'), 632 - self.fileActivated) 633 + self.doubleClicked.connect(self.fileActivated) 634 635 - connect(self.horizontalHeader(), 636 - SIGNAL('sectionResized(int, int, int)'), 637 + self.horizontalHeader().sectionResized[int, int, int].connect( 638 self.sectionResized) 639 self._diff_dialogs = {} 640 self._nav_dialogs = {} 641 642 def setModel(self, model): 643 QtGui.QTableView.setModel(self, model) 644 - connect(model, SIGNAL('layoutChanged()'), 645 - self.fileSelected) 646 - connect(self.selectionModel(), 647 - SIGNAL('currentRowChanged (const QModelIndex & , const QModelIndex & )'), 648 + model.layoutChanged.connect(self.fileSelected) 649 + self.selectionModel().currentRowChanged.connect( 650 self.fileSelected) 651 self.horizontalHeader().setResizeMode(1, QtGui.QHeaderView.Stretch) 652 653 def currentFile(self): 654 index = self.currentIndex()
@@ -620,11 +614,15 @@
655 def fileSelected(self, index=None, *args): 656 if index is None: 657 index = self.currentIndex() 658 sel_file = self.model().fileFromIndex(index) 659 from_rev = self.model().revFromIndex(index) 660 - self.emit(SIGNAL('fileSelected'), sel_file, from_rev) 661 + # signal get unicode as input 662 + if from_rev is None: 663 + self.file_selected[str].emit(tounicode(sel_file)) 664 + else: 665 + self.file_selected[str, int].emit(to_unicode(sel_file), from_rev) 666 667 def selectFile(self, filename): 668 self.setCurrentIndex(self.model().indexFromFile(filename)) 669 670 def fileActivated(self, index, alternate=False):
@@ -679,11 +677,11 @@
671 if tip: 672 act.setStatusTip(tip) 673 if key: 674 act.setShortcut(key) 675 if cb: 676 - connect(act, SIGNAL('triggered()'), cb) 677 + act.triggered.connect(cb) 678 self._actions[name] = act 679 self.addAction(act) 680 681 def contextMenuEvent(self, event): 682 menu = QtGui.QMenu(self)
@@ -32,14 +32,10 @@
683 from hgviewlib.qt4 import icon as geticon 684 from hgviewlib.qt4.hgdialogmixin import HgDialogMixin 685 from hgviewlib.qt4.hgrepomodel import ManifestModel 686 from hgviewlib.qt4.lexers import get_lexer 687 688 -connect = QtCore.QObject.connect 689 -disconnect = QtCore.QObject.disconnect 690 -SIGNAL = QtCore.SIGNAL 691 - 692 693 class ManifestViewer(QtGui.QMainWindow, HgDialogMixin, _ManifestViewer): 694 """ 695 Qt4 dialog to display all files of a repo at a given revision 696 """
@@ -63,17 +59,15 @@
697 self.max_file_size = cfg.getMaxFileSize() 698 699 def setupModels(self): 700 self.treemodel = ManifestModel(self.repo, self.rev) 701 self.treeView.setModel(self.treemodel) 702 - connect(self.treeView.selectionModel(), 703 - SIGNAL('currentChanged(const QModelIndex &, const QModelIndex &)'), 704 - self.fileSelected) 705 + self.treeView.selectionModel().currentChanged.connect( 706 + self.fileSelected) 707 708 def createActions(self): 709 - connect(self.actionClose, SIGNAL('triggered()'), 710 - self.close) 711 + self.actionClose.triggered.connect(self.close) 712 self.actionClose.setIcon(geticon('quit')) 713 714 def setupTextview(self): 715 lay = QtGui.QHBoxLayout(self.mainFrame) 716 lay.setSpacing(0)
@@ -32,14 +32,12 @@
717 from hgviewlib.qt4 import icon as geticon 718 from hgviewlib.decorators import timeit 719 from hgviewlib.hgpatches import phases 720 721 from PyQt4.QtGui import QColor, QPixmap, QPainter, QPen, QFont 722 -from PyQt4.QtCore import Qt, SIGNAL, QAbstractItemModel, QAbstractTableModel, \ 723 - QObject, QDateTime, QTimer, QModelIndex, QPointF 724 -connect = QObject.connect 725 -SIGNAL = SIGNAL 726 +from PyQt4.QtCore import Qt, pyqtSignal, QAbstractItemModel, QAbstractTableModel, \ 727 + QObject, QDateTime, QTimer, QModelIndex, QVariant, QPointF 728 729 # XXX make this better than a poor hard written list... 730 COLORS = [ "blue", "darkgreen", "red", "green", "darkblue", "purple", 731 "cyan", Qt.darkYellow, "magenta", "darkred", "darkmagenta", 732 "darkcyan", "gray", ]
@@ -240,10 +238,14 @@
733 734 class HgRepoListModel(QAbstractTableModel, HgRepoListWalker, GraphCtxMixin): 735 """ 736 Model used for displaying the revisions of a Hg *local* repository 737 """ 738 + 739 + message_logged = pyqtSignal(str, int) 740 + filled = pyqtSignal() 741 + 742 _allcolumns = ('ID', 'Branch', 'Log', 'Author', 'Date', 'Tags',) 743 _columns = ('ID', 'Branch', 'Log', 'Author', 'Date', 'Tags',) 744 _stretchs = {'Log': 1, } 745 _getcolumns = "getChangelogColumns" 746
@@ -256,36 +258,36 @@
747 HgRepoListWalker.__init__(self, repo, branch, fromhead, follow, closed=closed) 748 self.highlights = [] 749 750 def setRepo(self, repo, branch='', fromhead=None, follow=False, closed=False): 751 HgRepoListWalker.setRepo(self, repo, branch, fromhead, follow, closed=closed) 752 - self.emit(SIGNAL('layoutChanged()')) 753 - QTimer.singleShot(0, partial(self.emit, SIGNAL('filled'))) 754 + self.layoutChanged.emit() 755 + QTimer.singleShot(0, self.filled.emit) 756 self._fill_timer = self.startTimer(50) 757 758 def highlight_rows(self, rows): 759 """mark ``rows`` to be highlighted.""" 760 self.highlights[:] = rows 761 self._datacache.clear() 762 763 def timerEvent(self, event): 764 if event.timerId() == self._fill_timer: 765 - self.emit(SIGNAL('showMessage'), 766 + self.message_logged.emit( 767 'filling (%s)' % (len(self.graph)), 768 -1) 769 if self.graph.isfilled(): 770 self.killTimer(self._fill_timer) 771 self._fill_timer = None 772 - self.emit(SIGNAL('showMessage'), '', -1) 773 + self.message_logged.emit('', -1) 774 # we fill the graph data structures without telling 775 # views until we are done - this gives 776 # maximal GUI responsiveness 777 elif not self.graph.build_nodes(nnodes=self.fill_step): 778 self.killTimer(self._fill_timer) 779 self._fill_timer = None 780 self.updateRowCount() 781 - self.emit(SIGNAL('showMessage'), '', -1) 782 + self.message_logged.emit('', -1) 783 784 def updateRowCount(self): 785 currentlen = self.rowcount 786 newlen = len(self.graph) 787 if newlen > self.rowcount:
@@ -400,11 +402,11 @@
788 self.graph = None 789 self._datacache = {} 790 self.notify_data_changed() 791 792 def notify_data_changed(self): 793 - self.emit(SIGNAL("layoutChanged()")) 794 + self.layoutChanged.emit() 795 796 def indexFromRev(self, rev): 797 self.ensureBuilt(rev=rev) 798 row = self.rowFromRev(rev) 799 if row is not None:
@@ -448,11 +450,11 @@
800 # we use fl.index here (instead of linkrev) cause 801 # linkrev API changed between 1.0 and 1.?. So this 802 # works with both versions. 803 self.heads = [fl.index[fl.rev(x)][4] for x in fl.heads()] 804 self.ensureBuilt(row=self.fill_step/2) 805 - QTimer.singleShot(0, partial(self.emit, SIGNAL('filled'))) 806 + QTimer.singleShot(0, self.filled.emit) 807 self._fill_timer = self.startTimer(500) 808 else: 809 self.graph = None 810 self.heads = [] 811
@@ -484,11 +486,11 @@
812 self._fill_iter = None 813 814 def toggleFullFileList(self): 815 self._fulllist = not self._fulllist 816 self.loadFiles() 817 - self.emit(SIGNAL('layoutChanged()')) 818 + self.layoutChanged.emit() 819 820 def load_config(self): 821 cfg = HgConfig(self.repo.ui) 822 self._flagcolor = {} 823 self._flagcolor['='] = cfg.getFileModifiedColor()
@@ -501,11 +503,11 @@
824 825 def setDiffWidth(self, w): 826 if w != self.diffwidth: 827 self.diffwidth = w 828 self._datacache = {} 829 - self.emit(SIGNAL('dataChanged(const QModelIndex &, const QModelIndex & )'), 830 + self.dataChanged.emit( 831 self.index(1, 0), 832 self.index(1, self.rowCount())) 833 834 def __len__(self): 835 return len(self._files)
@@ -592,11 +594,11 @@
836 def setSelectedRev(self, ctx): 837 if ctx != self.current_ctx: 838 self.current_ctx = ctx 839 self._datacache = {} 840 self.loadFiles() 841 - self.emit(SIGNAL("layoutChanged()")) 842 + self.layoutChanged.emit() 843 844 def fillFileStats(self): 845 """ 846 Method called to start the background process of computing 847 file stats, which are to be displayed in the 'Stats' column
@@ -610,12 +612,11 @@
848 try: 849 nextfill = self._fill_iter.next() 850 if nextfill is not None: 851 row, col = nextfill 852 idx = self.index(row, col) 853 - self.emit(SIGNAL('dataChanged(const QModelIndex &, const QModelIndex &)'), 854 - idx, idx) 855 + self.dataChanged.emit(idx, idx) 856 QTimer.singleShot(10, lambda self=self: self._fill_one_step()) 857 858 except StopIteration: 859 self._fill_iter = None 860
@@ -24,14 +24,12 @@
861 862 from mercurial.error import (RepoError, ParseError, LookupError, 863 RepoLookupError, Abort) 864 865 from PyQt4 import QtCore, QtGui 866 +from PyQt4.QtCore import pyqtSignal 867 Qt = QtCore.Qt 868 -connect = QtCore.QObject.connect 869 -disconnect = QtCore.QObject.disconnect 870 -SIGNAL = QtCore.SIGNAL 871 872 from hgviewlib.decorators import timeit 873 from hgviewlib.config import HgConfig 874 from hgviewlib.hgpatches.scmutil import revrange 875 from hgviewlib.util import format_desc, xml_escape, tounicode
@@ -65,10 +63,14 @@
876 877 878 class GotoQuery(QtCore.QThread): 879 """A dedicated thread that queries a revset to the repo related to 880 the model""" 881 + 882 + failed_revset = pyqtSignal(str) 883 + new_revset = pyqtSignal(tuple, str) 884 + 885 def __init__(self): 886 super(GotoQuery, self).__init__() 887 self.rows = None 888 self.revexp = None 889 self.model = None
@@ -80,21 +82,21 @@
890 revset = None 891 try: 892 revset = revrange(self.model.repo, [self.revexp.encode('utf-8')]) 893 except (RepoError, ParseError, LookupError, RepoLookupError, Abort), err: 894 self.rows = None 895 - self.emit(SIGNAL('failed_revset'), err) 896 + self.failed_revset.emit(tounicode(err)) 897 return 898 if revset is None: 899 self.rows = () 900 - self.emit(SIGNAL('new_revset'), self.rows, self.revexp) 901 + self.new_revset.emit(self.rows, self.revexp) 902 return 903 rows = (idx.row() for idx in 904 (self.model.indexFromRev(rev) for rev in revset) 905 if idx is not None) 906 self.rows = tuple(sorted(rows)) 907 - self.emit(SIGNAL('new_revset'), self.rows, self.revexp) 908 + self.new_revset.emit(self.rows, self.revexp) 909 910 def perform(self, revexp, model): 911 self.terminate() 912 self.revexp = revexp 913 self.model = model
@@ -117,15 +119,20 @@
914 self.setStringList(strings) 915 916 917 class QueryLineEdit(QtGui.QLineEdit): 918 """Special LineEdit class with visual marks for the revset query status""" 919 + 920 + text_edited_no_blank = pyqtSignal(str) 921 + 922 FORGROUNDS = {'normal':Qt.color1, 923 'valid':Qt.color1, 924 'failed':Qt.darkRed, 925 'query':Qt.darkGray} 926 + 927 ICONS = {'valid':'valid', 'query':'loading'} 928 + 929 def __init__(self, parent): 930 self._parent = parent 931 self._status = None # one of the keys of self.FORGROUNDS and self.ICONS 932 QtGui.QLineEdit.__init__(self, parent) 933 self.setTextMargins(0,0,-16,0)
@@ -155,14 +162,20 @@
934 def on_text_edited(self): 935 current_text = self.text().strip() 936 if current_text == self.previous_text: 937 return 938 self.previous_text = current_text 939 - self.emit(SIGNAL('text_edited_no_blank'), current_text) 940 + self.text_edited_no_blank.emit( current_text) 941 942 943 class GotoQuickBar(QuickBar): 944 + 945 + goto_strict_next_from = pyqtSignal(tuple) 946 + goto_strict_prev_from = pyqtSignal(tuple) 947 + new_set = pyqtSignal([], [tuple]) 948 + goto_next_from = pyqtSignal(tuple) 949 + 950 def __init__(self, parent): 951 self._parent = parent 952 self._goto_query = None 953 self.compl_model = None 954 self.completer = None
@@ -201,20 +214,20 @@
955 # entry 956 self.entry = QueryLineEdit(self) 957 self.entry.setCompleter(self.completer) 958 self.entry.setStatusTip("Enter a 'revset' to query a set of revisions") 959 self.addWidget(self.entry) 960 - connect(self.entry, SIGNAL('text_edited_no_blank'), self.auto_search) 961 + self.entry.text_edited_no_blank.connect(self.auto_search) 962 self.entry.returnPressed.connect(lambda: self.goto(True)) 963 # actions 964 self.addAction(self._actions['prev']) 965 self.addAction(self._actions['next']) 966 self.addAction(self._actions['help']) 967 # querier (threaded) 968 self._goto_query = GotoQuery() 969 - connect(self._goto_query, SIGNAL('failed_revset'), self.on_failed) 970 - connect(self._goto_query, SIGNAL('new_revset'), self.on_queried) 971 + self._goto_query.failed_revset.connect(self.on_failed) 972 + self._goto_query.new_revset.connect(self.on_queried) 973 974 def setVisible(self, visible=True): 975 QuickBar.setVisible(self, visible) 976 if visible: 977 self.entry.setFocus()
@@ -265,14 +278,14 @@
978 rows = self._goto_query.get_last_results() 979 if rows is None: 980 self.entry.status = 'failed' 981 return 982 if forward: 983 - signal = 'goto_strict_next_from' 984 + signal = self.goto_strict_next_from[tuple] 985 else: 986 - signal = 'goto_strict_prev_from' 987 - self.emit(SIGNAL(signal), rows) 988 + signal = self.goto_strict_prev_from[tuple] 989 + signal.emit(rows) 990 # usecase: enter a nodeid and hit enter to go on, 991 # so the goto tool bar is no more required and may be 992 # annoying 993 if rows and len(rows) == 1: 994 self.setVisible(False)
@@ -280,12 +293,12 @@
995 def search(self, revexp, threaded=True): 996 if revexp is None: 997 revexp = self._standby_revexp 998 self._standby_revexp = None 999 if not revexp: 1000 - self.emit(SIGNAL('new_set'), None) 1001 - self.emit(SIGNAL('goto_next_from'), (self.row_before,)) 1002 + self.new_set.emit() 1003 + self.goto_next_from[tuple].emit((self.row_before,)) 1004 return 1005 self.show_message("Querying ... (edit the entry to cancel)") 1006 self._actions['next'].setEnabled(False) 1007 self._actions['prev'].setEnabled(False) 1008 self.entry.status = 'query'
@@ -298,12 +311,12 @@
1009 self.parent().statusBar().showMessage(message, delay) 1010 1011 def on_queried(self, rows=None, revexp=u''): 1012 """Slot to handle new revset.""" 1013 self.entry.status = 'valid' 1014 - self.emit(SIGNAL('new_set'), rows) 1015 - self.emit(SIGNAL('goto_next_from'), rows) 1016 + self.new_set[tuple].emit(rows) 1017 + self.goto_next_from[tuple].emit(rows) 1018 self._actions['next'].setEnabled(True) 1019 self._actions['prev'].setEnabled(True) 1020 if rows and revexp: 1021 self.compl_model.add_to_string_list(revexp) 1022
@@ -317,10 +330,16 @@
1023 class HgRepoView(QtGui.QTableView): 1024 """ 1025 A QTableView for displaying a FileRevModel or a HgRepoListModel, 1026 with actions, shortcuts, etc. 1027 """ 1028 + 1029 + start_from_rev = pyqtSignal([], [int, bool], [str, bool]) 1030 + revision_activated = pyqtSignal([], [int]) 1031 + revision_selected = pyqtSignal([], [int]) 1032 + message_logged = pyqtSignal(str, int) 1033 + 1034 def __init__(self, parent=None): 1035 QtGui.QTableView.__init__(self, parent) 1036 self.init_variables() 1037 self.setShowGrid(False) 1038 self.verticalHeader().hide()
@@ -329,18 +348,15 @@
1039 self.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) 1040 self.setAlternatingRowColors(True) 1041 1042 self.createActions() 1043 self.createToolbars() 1044 - connect(self, 1045 - SIGNAL('doubleClicked (const QModelIndex &)'), 1046 - self.revisionActivated) 1047 + self.doubleClicked.connect(self.revisionActivated) 1048 1049 self._autoresize = True 1050 - connect(self.horizontalHeader(), 1051 - SIGNAL('sectionResized(int, int, int)'), 1052 - self.disableAutoResize) 1053 + self.horizontalHeader().sectionResized[int, int, int].connect( 1054 + self.disableAutoResize) 1055 1056 def mousePressEvent(self, event): 1057 index = self.indexAt(event.pos()) 1058 if not index.isValid(): 1059 return
@@ -349,19 +365,18 @@
1060 return 1061 QtGui.QTableView.mousePressEvent(self, event) 1062 1063 def createToolbars(self): 1064 self.goto_toolbar = GotoQuickBar(self) 1065 - goto = self.goto_next_from 1066 - connect(self.goto_toolbar, SIGNAL('goto_strict_next_from'), 1067 + goto = self.on_goto_next_from 1068 + self.goto_toolbar.goto_strict_next_from[tuple].connect( 1069 lambda revs: goto(revs, strict=True, forward=True)) 1070 - connect(self.goto_toolbar, SIGNAL('goto_strict_prev_from'), 1071 + self.goto_toolbar.goto_strict_prev_from[tuple].connect( 1072 lambda revs: goto(revs, strict=True, forward=False)) 1073 - connect(self.goto_toolbar, SIGNAL('goto_next_from'), 1074 - lambda revs: goto(revs)) 1075 - connect(self.goto_toolbar, SIGNAL('new_set'), 1076 - self.highlight_rows) 1077 + self.goto_toolbar.goto_next_from[tuple].connect(goto) 1078 + self.goto_toolbar.new_set.connect(self.highlight_rows) 1079 + self.goto_toolbar.new_set[tuple].connect(self.highlight_rows) 1080 1081 def _action_defs(self): 1082 class ActDef(object): 1083 def __init__(self, name, desc, icon, tip, keys, cb): 1084 self.name = name
@@ -440,14 +455,16 @@
1085 if tip: 1086 act.setStatusTip(tip) 1087 if keys: 1088 act.setShortcuts(keys) 1089 if cb: 1090 - connect(act, SIGNAL('triggered()'), cb) 1091 + act.triggered.connect(cb) 1092 self.addAction(act) 1093 self._actions['unfilter'].setEnabled(False) 1094 - connect(self, SIGNAL('startFromRev'), self.update_filter_action) 1095 + self.start_from_rev.connect(self.update_filter_action) 1096 + self.start_from_rev[int, bool].connect(self.update_filter_action) 1097 + self.start_from_rev[str, bool].connect(self.update_filter_action) 1098 1099 def update_filter_action(self, rev=None, follow=None): 1100 self._actions['unfilter'].setEnabled(rev is not None) 1101 1102 def copy_cs_to_clipboard(self):
@@ -459,20 +476,29 @@
1103 u.pushbuffer() 1104 cmdutil.show_changeset(u, repo, {'template':template}, False).show(ctx) 1105 QtGui.QApplication.clipboard().setText(u.popbuffer()) 1106 1107 def showAtRev(self): 1108 - self.emit(SIGNAL('revisionActivated'), self.current_rev) 1109 + if self.current_rev is None: 1110 + self.revision_activated.emit() 1111 + else: 1112 + self.revision_activated[int].emit(self.current_rev) 1113 1114 def startFromRev(self): 1115 - self.emit(SIGNAL('startFromRev'), self.current_rev, False) 1116 + if self.current_rev is None: 1117 + self.start_from_rev.emit() 1118 + else: 1119 + self.start_from_rev[int, bool].emit(self.current_rev, False) 1120 1121 def followFromRev(self): 1122 - self.emit(SIGNAL('startFromRev'), self.current_rev, True) 1123 + if self.current_rev is None: 1124 + self.start_from_rev.emit() 1125 + else: 1126 + self.start_from_rev[int, bool].emit(self.current_rev, True) 1127 1128 def removeFilter(self): 1129 - self.emit(SIGNAL('startFromRev')) 1130 + self.start_from_rev.emit() 1131 1132 def contextMenuEvent(self, event): 1133 menu = QtGui.QMenu(self) 1134 for act in ['copycs', None, 1135 'manifest', None,
@@ -496,13 +522,11 @@
1136 # history navigation or if we are navigating the history 1137 1138 def setModel(self, model): 1139 self.init_variables() 1140 QtGui.QTableView.setModel(self, model) 1141 - connect(self.selectionModel(), 1142 - QtCore.SIGNAL('currentRowChanged (const QModelIndex & , const QModelIndex & )'), 1143 - self.revisionSelected) 1144 + self.selectionModel().currentRowChanged.connect(self.revisionSelected) 1145 tags = (tounicode(tag) for tag in model.repo.tags().keys()) 1146 self.goto_toolbar.compl_model.add_to_string_list(*tags) 1147 revaliases = [tounicode(item[0]) for item in model.repo.ui.configitems("revsetalias")] 1148 self.goto_toolbar.compl_model.add_to_string_list(*revaliases) 1149 col = list(model._columns).index('Log')
@@ -558,11 +582,11 @@
1150 return gnode.rev 1151 1152 def revisionActivated(self, index): 1153 rev = self.revFromindex(index) 1154 if rev is not None: 1155 - self.emit(SIGNAL('revisionActivated'), rev) 1156 + self.revision_activated[int].emit(rev) 1157 1158 def revisionSelected(self, index, index_from): 1159 """ 1160 Callback called when a revision is selected in the revisions table 1161 """
@@ -577,21 +601,24 @@
1162 self._rev_pos = len(self._rev_history)-1 1163 1164 self._in_history = False 1165 self.current_rev = rev 1166 1167 - self.emit(SIGNAL('revisionSelected'), rev) 1168 + if rev is None: 1169 + self.revision_selected.emit() 1170 + else: 1171 + self.revision_selected[int].emit(rev) 1172 self.set_navigation_button_state() 1173 1174 def gotoAncestor(self, index): 1175 rev = self.revFromindex(index) 1176 if rev is not None and self.current_rev is not None: 1177 repo = self.model().repo 1178 ctx = repo[self.current_rev] 1179 ctx2 = repo[rev] 1180 ancestor = ctx.ancestor(ctx2) 1181 - self.emit(SIGNAL('showMessage'), 1182 + self.message_logged.emit( 1183 "Goto ancestor of %s and %s"%(ctx.rev(), ctx2.rev()), 1184 5000) 1185 self.goto(ancestor.rev()) 1186 1187 def set_navigation_button_state(self):
@@ -620,11 +647,11 @@
1188 if idx is not None: 1189 self._in_history = True 1190 self.setCurrentIndex(idx) 1191 self.set_navigation_button_state() 1192 1193 - def goto(self, rev): 1194 + def goto(self, rev=None): 1195 """ 1196 Select revision 'rev'. 1197 It can be anything understood by repo.changectx(): 1198 revision number, node or tag for instance. 1199 """
@@ -632,19 +659,19 @@
1200 rev = rev.split(':')[1] 1201 repo = self.model().repo 1202 try: 1203 rev = repo.changectx(rev).rev() 1204 except RepoError: 1205 - self.emit(SIGNAL('showMessage'), 1206 + self.message_logged.emit( 1207 "Can't find revision '%s'" % rev, 2000) 1208 else: 1209 idx = self.model().indexFromRev(rev) 1210 if idx is not None: 1211 self.goto_toolbar.setVisible(False) 1212 self.setCurrentIndex(idx) 1213 1214 - def goto_next_from(self, rows, strict=False, forward=True): 1215 + def on_goto_next_from(self, rows, strict=False, forward=True): 1216 """Select the next row available in rows.""" 1217 if not rows: 1218 return 1219 currow = self.currentIndex().row() 1220 if strict:
@@ -660,11 +687,11 @@
1221 except StopIteration: 1222 self.visual_bell() 1223 row = rows[0 if forward else -1] 1224 self.setCurrentIndex(self.model().index(row, 0)) 1225 pos = rows.index(row) + 1 1226 - self.emit(SIGNAL('showMessage'), 1227 + self.message_logged.emit( 1228 "revision #%i of %i" % (pos, len(rows)), 1229 -1) 1230 1231 def nextRev(self): 1232 row = self.currentIndex().row()
@@ -672,16 +699,16 @@
1233 self.model().rowCount() - 1), 0)) 1234 def prevRev(self): 1235 row = self.currentIndex().row() 1236 self.setCurrentIndex(self.model().index(max(row - 1, 0), 0)) 1237 1238 - def highlight_rows(self, rows): 1239 + def highlight_rows(self, rows=None): 1240 if rows is None: 1241 self.visual_bell() 1242 - self.emit(SIGNAL('showMessage'), 'Revision set cleared.', 2000) 1243 + self.message_logged.emit('Revision set cleared.', 2000) 1244 else: 1245 - self.emit(SIGNAL('showMessage'), 1246 + self.message_logged.emit( 1247 '%i revisions found.' % len(rows), 1248 2000) 1249 self.model().highlight_rows(rows or ()) 1250 self.refresh_display() 1251
@@ -707,10 +734,14 @@
1252 TROUBLE_EXPLANATIONS['conflicting'] = TROUBLE_EXPLANATIONS['divergent'] 1253 class RevDisplay(QtGui.QTextBrowser): 1254 """ 1255 Display metadata for one revision (rev, author, description, etc.) 1256 """ 1257 + 1258 + parent_revision_selected = pyqtSignal([], [int]) 1259 + revision_selected = pyqtSignal([], [int]) 1260 + 1261 def __init__(self, parent=None): 1262 QtGui.QTextBrowser.__init__(self, parent) 1263 self.excluded = () 1264 self.descwidth = 60 # number of chars displayed for parent/child descriptions 1265
@@ -719,19 +750,16 @@
1266 self.rst_action.setCheckable(True) 1267 self.rst_action.setChecked(True) 1268 self.rst_action.setToolTip(self.tr('Interpret ReST comments')) 1269 self.rst_action.setStatusTip(self.tr('Interpret ReST comments')) 1270 1271 - connect(self.rst_action, SIGNAL('triggered()'), 1272 - self.refreshDisplay) 1273 + self.rst_action.triggered.connect(self.refreshDisplay) 1274 else: 1275 self.rst_action = None 1276 - connect(self, 1277 - SIGNAL('anchorClicked(const QUrl &)'), 1278 - self.anchorClicked) 1279 + self.anchorClicked.connect(self.on_anchor_clicked) 1280 1281 - def anchorClicked(self, qurl): 1282 + def on_anchor_clicked(self, qurl): 1283 """ 1284 Callback called when a link is clicked in the text browser 1285 """ 1286 rev = qurl.toString() 1287 diff = False
@@ -747,13 +775,19 @@
1288 1289 if diff: 1290 self.diffrev = rev 1291 self.refreshDisplay() 1292 # TODO: emit a signal to recompute the diff 1293 - self.emit(SIGNAL('parentRevisionSelected'), self.diffrev) 1294 + if self.diffrev is None: 1295 + self.parent_revision_selected.emit() 1296 + else: 1297 + self.parent_revision_selected[int].emit(self.diffrev) 1298 else: 1299 - self.emit(SIGNAL('revisionSelected'), rev) 1300 + if rev is None: 1301 + self.revision_selected.emit() 1302 + else: 1303 + self.revision_selected[int].emit(rev) 1304 1305 def setDiffRevision(self, rev): 1306 if rev != self.diffrev: 1307 self.diffrev = rev 1308 self.refreshDisplay()
@@ -6,15 +6,17 @@
1309 # This software may be used and distributed according to the terms 1310 # of the GNU General Public License, incorporated herein by reference. 1311 """ 1312 Main Qt4 application for hgview 1313 """ 1314 + 1315 import sys, os 1316 import os.path as osp 1317 import re 1318 import errno 1319 from functools import partial 1320 +from operator import methodcaller 1321 1322 from PyQt4 import QtCore, QtGui, Qsci 1323 1324 from mercurial import ui, hg 1325 from mercurial import util
@@ -40,12 +42,10 @@
1326 1327 from mercurial.error import RepoError 1328 1329 Qt = QtCore.Qt 1330 bold = QtGui.QFont.Bold 1331 -connect = QtCore.QObject.connect 1332 -SIGNAL = QtCore.SIGNAL 1333 1334 NESTED_PREFIX = u'\N{RIGHTWARDS ARROW} ' 1335 1336 class HgRepoViewer(QtGui.QMainWindow, HgDialogMixin, _HgRepoViewer): 1337 """hg repository viewer/browser application"""
@@ -76,31 +76,32 @@
1338 1339 self.createActions() 1340 self.createToolbars() 1341 1342 self.textview_status.setFont(self._font) 1343 - connect(self.textview_status, SIGNAL('showMessage'), 1344 + self.textview_status.message_logged.connect( 1345 self.statusBar().showMessage) 1346 - connect(self.tableView_revisions, SIGNAL('showMessage'), 1347 + self.tableView_revisions.message_logged.connect( 1348 self.statusBar().showMessage) 1349 1350 # setup tables and views 1351 if self.repo.root is not None: 1352 1353 self.setupHeaderTextview() 1354 self.setupBranchCombo() 1355 self.setupModels(fromhead) 1356 self._setupQuickOpen() 1357 1358 + to_utf8 = methodcaller('encode', 'utf-8') 1359 if self.cfg.getFileDescriptionView() == 'asfile': 1360 - fileselcallback = self.displaySelectedFile 1361 + fileselcallback = compose(self.displaySelectedFile, to_utf8) 1362 else: 1363 - fileselcallback = self.textview_status.displayFile 1364 - connect(self.tableView_filelist, SIGNAL('fileSelected'), 1365 - fileselcallback) 1366 + fileselcallback = compose(self.textview_status.displayFile, to_utf8) 1367 + self.tableView_filelist.file_selected[str].connect(fileselcallback) 1368 + self.tableView_filelist.file_selected[str, int].connect(fileselcallback) 1369 1370 - connect(self.textview_status, SIGNAL('revForDiffChanged'), 1371 + self.textview_status.rev_for_diff_changed.connect( 1372 self.textview_header.setDiffRevision) 1373 1374 if fromhead: 1375 self.startrev_entry.setText(str(fromhead)) 1376 self.setupRevisionTable()
@@ -185,15 +186,17 @@
1377 def createToolbars(self): 1378 # find quickbar 1379 self.find_toolbar = FindInGraphlogQuickBar(self) 1380 self.find_toolbar.attachFileView(self.textview_status) 1381 self.find_toolbar.attachHeaderView(self.textview_header) 1382 - connect(self.find_toolbar, SIGNAL('revisionSelected'), 1383 + self.find_toolbar.revision_selected.connect( 1384 self.tableView_revisions.goto) 1385 - connect(self.find_toolbar, SIGNAL('fileSelected'), 1386 + self.find_toolbar.revision_selected[int].connect( 1387 + self.tableView_revisions.goto) 1388 + self.find_toolbar.file_selected.connect( 1389 self.tableView_filelist.selectFile) 1390 - connect(self.find_toolbar, SIGNAL('showMessage'), 1391 + self.find_toolbar.message_logged.connect( 1392 self.statusBar().showMessage, 1393 Qt.QueuedConnection) 1394 1395 self.attachQuickBar(self.find_toolbar) 1396
@@ -225,14 +228,12 @@
1397 cbranch_action = self.branch_menu.addAction("Display closed branches") 1398 cbranch_action.setCheckable(True) 1399 self.branch_checkBox_action = cbranch_action 1400 self.branch_label.setMenu(self.branch_menu) 1401 self.branch_comboBox = QtGui.QComboBox() 1402 - connect(self.branch_comboBox, SIGNAL('activated(const QString &)'), 1403 - self.refreshRevisionTable) 1404 - connect(cbranch_action, SIGNAL('toggled(bool)'), 1405 - self.setupBranchComboAndReload) 1406 + self.branch_comboBox.activated[str].connect(self.refreshRevisionTable) 1407 + cbranch_action.toggled[bool].connect(self.setupBranchComboAndReload) 1408 1409 self.toolBar_treefilters.layout().setSpacing(3) 1410 1411 self.branch_label_action = self.toolBar_treefilters.addWidget(self.branch_label) 1412 self.branch_comboBox_action = self.toolBar_treefilters.addWidget(self.branch_comboBox)
@@ -249,15 +250,14 @@
1413 follow_action = self.startrev_menu.addAction("Follow mode") 1414 follow_action.setCheckable(True) 1415 follow_action.setStatusTip("Follow changeset history from start revision") 1416 self.startrev_follow_action = follow_action 1417 self.startrev_label.setMenu(self.startrev_menu) 1418 - callback = lambda *a: self.tableView_revisions.emit( 1419 - SIGNAL('startFromRev'), 1420 - self.startrev_entry, self.startrev_follow_action) 1421 - connect(self.startrev_entry, SIGNAL('editingFinished()'), callback) 1422 - connect(self.startrev_follow_action, SIGNAL('toggled(bool)'), callback) 1423 + callback = lambda *a: self.tableView_revisions.start_from_rev[str, bool].emit( 1424 + str(self.startrev_entry.text()), self.startrev_follow_action.isChecked()) 1425 + self.startrev_entry.editingFinished.connect(callback) 1426 + self.startrev_follow_action.toggled[bool].connect(callback) 1427 1428 self.revscompl_model = QtGui.QStringListModel(['tip']) 1429 self.revcompleter = QtGui.QCompleter(self.revscompl_model, self) 1430 self.startrev_entry.setCompleter(self.revcompleter) 1431
@@ -309,111 +309,95 @@
1432 ) 1433 1434 1435 def createActions(self): 1436 # main window actions (from .ui file) 1437 - connect(self.actionOpen_repository, SIGNAL('triggered()'), 1438 - self.open_repository) 1439 - connect(self.actionRefresh, SIGNAL('triggered()'), 1440 - self.reload) 1441 - connect(self.actionAbout, SIGNAL('triggered()'), 1442 - self.on_about) 1443 - connect(self.actionQuit, SIGNAL('triggered()'), 1444 - self.close) 1445 + self.actionOpen_repository.triggered.connect(self.open_repository) 1446 + self.actionRefresh.triggered.connect(self.reload) 1447 + self.actionAbout.triggered.connect(self.on_about) 1448 + self.actionQuit.triggered.connect(self.close) 1449 self.actionQuit.setIcon(geticon('quit')) 1450 self.actionRefresh.setIcon(geticon('reload')) 1451 1452 self.actionHelp.setShortcut(Qt.Key_F1) 1453 self.actionHelp.setIcon(geticon('help')) 1454 - connect(self.actionHelp, SIGNAL('triggered()'), 1455 - self.on_help) 1456 + self.actionHelp.triggered.connect(self.on_help) 1457 1458 self.actionShowHidden = QtGui.QAction(self.tr('Show/Hide Hidden'), self) 1459 self.actionShowHidden.setIcon(geticon('showhide')) 1460 self.actionShowHidden.setCheckable(True) 1461 self.actionShowHidden.setChecked(self.cfg.getShowHidden()) 1462 self.actionShowHidden.setToolTip(self.tr('Show/Hide hidden changeset')) 1463 self.actionShowHidden.setStatusTip(self.tr('Show/hide hidden changeset')) 1464 - connect(self.actionShowHidden, SIGNAL('triggered()'), 1465 - self.refreshRevisionTable) 1466 + self.actionShowHidden.triggered.connect(self.refreshRevisionTable) 1467 1468 self.actionShowMainContent = QtGui.QAction('Content', self) 1469 self.actionShowMainContent.setIcon(geticon('content')) 1470 self.actionShowMainContent.setCheckable(True) 1471 self.actionShowMainContent.setChecked(self.cfg.getContentAtStartUp()) 1472 tip = self.tr('Show/Hide changeset content') 1473 self.actionShowMainContent.setToolTip(tip) 1474 self.actionShowMainContent.setStatusTip(tip) 1475 self.actionShowMainContent.setShortcut(Qt.Key_Space) 1476 - connect(self.actionShowMainContent, SIGNAL('triggered()'), 1477 - self.toggleMainContent) 1478 + self.actionShowMainContent.triggered.connect(self.toggleMainContent) 1479 1480 # Next/Prev file 1481 self.actionNextFile = QtGui.QAction('Next file', self) 1482 self.actionNextFile.setShortcut('Right') 1483 - connect(self.actionNextFile, SIGNAL('triggered()'), 1484 - self.tableView_filelist.nextFile) 1485 + self.actionNextFile.triggered.connect(self.tableView_filelist.nextFile) 1486 self.actionPrevFile = QtGui.QAction('Prev file', self) 1487 self.actionPrevFile.setShortcut('Left') 1488 - connect(self.actionPrevFile, SIGNAL('triggered()'), 1489 - self.tableView_filelist.prevFile) 1490 + self.actionPrevFile.triggered.connect(self.tableView_filelist.prevFile) 1491 self.addAction(self.actionNextFile) 1492 self.addAction(self.actionPrevFile) 1493 self.disab_shortcuts.append(self.actionNextFile) 1494 self.disab_shortcuts.append(self.actionPrevFile) 1495 1496 # Next/Prev rev 1497 self.actionNextRev = QtGui.QAction('Next revision', self) 1498 self.actionNextRev.setShortcut('Down') 1499 - connect(self.actionNextRev, SIGNAL('triggered()'), 1500 - self.tableView_revisions.nextRev) 1501 + self.actionNextRev.triggered.connect(self.tableView_revisions.nextRev) 1502 self.actionPrevRev = QtGui.QAction('Prev revision', self) 1503 self.actionPrevRev.setShortcut('Up') 1504 - connect(self.actionPrevRev, SIGNAL('triggered()'), 1505 - self.tableView_revisions.prevRev) 1506 + self.actionPrevRev.triggered.connect(self.tableView_revisions.prevRev) 1507 self.addAction(self.actionNextRev) 1508 self.addAction(self.actionPrevRev) 1509 self.disab_shortcuts.append(self.actionNextRev) 1510 self.disab_shortcuts.append(self.actionPrevRev) 1511 1512 # navigate in file viewer 1513 self.actionNextLine = QtGui.QAction('Next line', self) 1514 self.actionNextLine.setShortcut(Qt.SHIFT + Qt.Key_Down) 1515 - connect(self.actionNextLine, SIGNAL('triggered()'), 1516 - self.textview_status.nextLine) 1517 + self.actionNextLine.triggered.connect(self.textview_status.nextLine) 1518 self.addAction(self.actionNextLine) 1519 self.actionPrevLine = QtGui.QAction('Prev line', self) 1520 self.actionPrevLine.setShortcut(Qt.SHIFT + Qt.Key_Up) 1521 - connect(self.actionPrevLine, SIGNAL('triggered()'), 1522 - self.textview_status.prevLine) 1523 + self.actionPrevLine.triggered.connect(self.textview_status.prevLine) 1524 self.addAction(self.actionPrevLine) 1525 self.actionNextCol = QtGui.QAction('Next column', self) 1526 self.actionNextCol.setShortcut(Qt.SHIFT + Qt.Key_Right) 1527 - connect(self.actionNextCol, SIGNAL('triggered()'), 1528 - self.textview_status.nextCol) 1529 + self.actionNextCol.triggered.connect(self.textview_status.nextCol) 1530 self.addAction(self.actionNextCol) 1531 self.actionPrevCol = QtGui.QAction('Prev column', self) 1532 self.actionPrevCol.setShortcut(Qt.SHIFT + Qt.Key_Left) 1533 - connect(self.actionPrevCol, SIGNAL('triggered()'), 1534 - self.textview_status.prevCol) 1535 + self.actionPrevCol.triggered.connect(self.textview_status.prevCol) 1536 self.addAction(self.actionPrevCol) 1537 1538 # Activate file (file diff navigator) 1539 self.actionActivateFile = QtGui.QAction('Activate file', self) 1540 self.actionActivateFile.setShortcuts([Qt.Key_Return, Qt.Key_Enter]) 1541 def enterkeypressed(): 1542 w = QtGui.QApplication.focusWidget() 1543 if not isinstance(w, QtGui.QLineEdit): 1544 self.tableView_filelist.fileActivated(self.tableView_filelist.currentIndex(),) 1545 else: 1546 - w.emit(SIGNAL('editingFinished()')) 1547 - connect(self.actionActivateFile, SIGNAL('triggered()'), 1548 - enterkeypressed) 1549 + w.editingFinished.emit() 1550 + self.actionActivateFile.triggered.connect(enterkeypressed) 1551 1552 self.actionActivateFileAlt = QtGui.QAction('Activate alt. file', self) 1553 self.actionActivateFileAlt.setShortcuts([Qt.ALT+Qt.Key_Return, Qt.ALT+Qt.Key_Enter]) 1554 - connect(self.actionActivateFileAlt, SIGNAL('triggered()'), 1555 + self.actionActivateFileAlt.triggered.connect( 1556 lambda self=self: 1557 self.tableView_filelist.fileActivated(self.tableView_filelist.currentIndex(), 1558 alternate=True)) 1559 1560 def toggleMainContent(self, visible=None):
@@ -434,13 +418,12 @@
1561 cfg = HgDialogMixin.load_config(self) 1562 self.hidefinddelay = cfg.getHideFindDelay() 1563 1564 def create_models(self, fromhead=None): 1565 self.repomodel = HgRepoListModel(self.repo, fromhead=fromhead) 1566 - connect(self.repomodel, SIGNAL('filled'), 1567 - self.on_filled) 1568 - connect(self.repomodel, SIGNAL('showMessage'), 1569 + self.repomodel.filled.connect(self.on_filled) 1570 + self.repomodel.message_logged.connect( 1571 self.statusBar().showMessage, 1572 Qt.QueuedConnection) 1573 1574 self.filelistmodel = HgFileListModel(self.repo) 1575
@@ -462,32 +445,33 @@
1576 self.textview_status.displayFile(filename, rev) 1577 1578 def setupRevisionTable(self): 1579 view = self.tableView_revisions 1580 view.installEventFilter(self) 1581 - connect(view, SIGNAL('clicked (const QModelIndex &)'), 1582 - self.toggleMainContent) 1583 - connect(view, SIGNAL('revisionSelected'), self.revision_selected) 1584 - connect(view, SIGNAL('revisionActivated'), self.revision_activated) 1585 - connect(view, SIGNAL('startFromRev'), self.start_from_rev) 1586 - connect(self.textview_header, SIGNAL('revisionSelected'), view.goto) 1587 - connect(self.textview_header, SIGNAL('parentRevisionSelected'), 1588 + view.clicked.connect(self.toggleMainContent) 1589 + view.revision_selected.connect(self.revision_selected) 1590 + view.revision_selected[int].connect(self.revision_selected) 1591 + view.revision_activated.connect(self.revision_activated) 1592 + view.revision_activated[int].connect(self.revision_activated) 1593 + view.start_from_rev.connect(self.start_from_rev) 1594 + view.start_from_rev[int, bool].connect(self.start_from_rev) 1595 + view.start_from_rev[str, bool].connect(self.start_from_rev) 1596 + self.textview_header.revision_selected.connect(view.goto) 1597 + self.textview_header.revision_selected[int].connect(view.goto) 1598 + self.textview_header.parent_revision_selected.connect( 1599 + self.textview_status.displayDiff) 1600 + self.textview_header.parent_revision_selected[int].connect( 1601 self.textview_status.displayDiff) 1602 self.attachQuickBar(view.goto_toolbar) 1603 gotoaction = view.goto_toolbar.toggleViewAction() 1604 gotoaction.setIcon(geticon('goto')) 1605 self.toolBar_edit.addAction(gotoaction) 1606 1607 def start_from_rev(self, rev=None, follow=False): 1608 - if rev == self.startrev_entry: 1609 - rev = str(self.startrev_entry.text()).strip() or None 1610 - if follow == self.startrev_follow_action: 1611 - follow = self.startrev_follow_action.isChecked() 1612 - 1613 + rev = rev or None # '' => None 1614 self.startrev_entry.setText(str(rev or '')) 1615 self.startrev_follow_action.setChecked(follow) 1616 - 1617 self.refreshRevisionTable(rev=rev, follow=follow) 1618 1619 def _setup_table(self, table): 1620 table.setTabKeyNavigation(False) 1621 table.verticalHeader().setDefaultSectionSize(self.rowheight)
@@ -537,11 +521,11 @@
1622 rev = self.tableView_revisions.current_rev 1623 self.toggleMainContent(True) 1624 self._manifestdlg = ManifestViewer(self.repo, rev) 1625 self._manifestdlg.show() 1626 1627 - def revision_selected(self, rev): 1628 + def revision_selected(self, rev=None): 1629 """ 1630 Callback called when a revision is selected in the revisions table 1631 if rev == -1: refresh the current selected revision 1632 """ 1633 if not self.frame_maincontent.isVisible() or not self.repomodel.graph:
@@ -20,20 +20,23 @@
1634 from functools import partial 1635 1636 from mercurial import util 1637 1638 from PyQt4 import QtCore, QtGui 1639 +from PyQt4.QtCore import pyqtSignal 1640 1641 from hgviewlib.util import tounicode 1642 from hgviewlib.qt4 import icon as geticon 1643 1644 Qt = QtCore.Qt 1645 -connect = QtCore.QObject.connect 1646 -SIGNAL = QtCore.SIGNAL 1647 1648 1649 class QuickBar(QtGui.QToolBar): 1650 + 1651 + esc_shortcut_disabled = pyqtSignal(bool) 1652 + unhidden = pyqtSignal() 1653 + 1654 def __init__(self, name, key, desc=None, parent=None): 1655 self.original_parent = parent 1656 # used to remember who had the focus before bar steel it 1657 self._focusw = None 1658 QtGui.QToolBar.__init__(self, name, parent)
@@ -57,27 +60,25 @@
1659 desc = "Open" 1660 openact = QtGui.QAction(desc, parent) 1661 openact.setCheckable(True) 1662 openact.setChecked(False) 1663 openact.setShortcut(QtGui.QKeySequence(openkey)) 1664 - connect(openact, SIGNAL('triggered()'), 1665 - partial(self.setVisible, True)) 1666 + openact.triggered.connect(partial(self.setVisible, True)) 1667 1668 closeact = QtGui.QAction('Close', self) 1669 closeact.setIcon(geticon('close')) 1670 - connect(closeact, SIGNAL('triggered()'), 1671 - partial(self.setVisible, False)) 1672 + closeact.triggered.connect(partial(self.setVisible, False)) 1673 1674 self._actions = {'open': openact, 1675 'close': closeact,} 1676 1677 def setVisible(self, visible=True): 1678 if visible and not self.isVisible(): 1679 - self.emit(SIGNAL('visible')) 1680 + self.unhidden.emit() 1681 self._focusw = QtGui.QApplication.focusWidget() 1682 QtGui.QToolBar.setVisible(self, visible) 1683 - self.emit(SIGNAL('escShortcutDisabled(bool)'), not visible) 1684 + self.esc_shortcut_disabled[bool].emit(not visible) 1685 if not visible and self._focusw: 1686 self._focusw.setFocus() 1687 self._focusw = None 1688 1689 def createContent(self):
@@ -96,39 +97,45 @@
1690 shortcuts.append(key) 1691 act.setShortcuts(shortcuts) 1692 1693 1694 class FindQuickBar(QuickBar): 1695 + 1696 + to_find = pyqtSignal(str) 1697 + to_find_next = pyqtSignal(str) 1698 + canceled = pyqtSignal() 1699 + message_logged = pyqtSignal(str, int) 1700 + 1701 def __init__(self, parent): 1702 QuickBar.__init__(self, "Find", "/", "Find", parent) 1703 self.addShortcut('open', 'Ctrl+F') 1704 self.currenttext = '' 1705 1706 def createActions(self, openkey, desc): 1707 QuickBar.createActions(self, openkey, desc) 1708 self._actions['findnext'] = QtGui.QAction("Find next", self) 1709 self._actions['findnext'].setShortcut(QtGui.QKeySequence("Ctrl+N")) 1710 - connect(self._actions['findnext'], SIGNAL('triggered()'), self.find) 1711 + self._actions['findnext'].triggered.connect(self.find) 1712 self._actions['cancel'] = QtGui.QAction("Cancel", self) 1713 - connect(self._actions['cancel'], SIGNAL('triggered()'), self.cancel) 1714 + self._actions['cancel'].triggered.connect(self.cancel) 1715 1716 def find(self, *args): 1717 '''Scan the repository metadata and search for occurrences of the 1718 text in the entry. 1719 :note: do not scan if no text was provided''' 1720 text = self.entry.text() 1721 if not text: # do not strip() as user may want to find space sequences 1722 - self.emit(SIGNAL('showMessage'), 'Nothing to look for.', 1000) 1723 + self.message_logged.emit('Nothing to look for.', 1000) 1724 return 1725 if text == self.currenttext: 1726 - self.emit(SIGNAL('findnext'), text) 1727 + self.to_find_next.emit(text) 1728 else: 1729 self.currenttext = text 1730 - self.emit(SIGNAL('find'), text) 1731 + self.to_find.emit(text) 1732 1733 def cancel(self): 1734 - self.emit(SIGNAL('cancel')) 1735 + self.canceled.emit() 1736 1737 def setCancelEnabled(self, enabled=True): 1738 self._actions['cancel'].setEnabled(enabled) 1739 self._actions['findnext'].setEnabled(not enabled) 1740
@@ -141,14 +148,12 @@
1741 self.addWidget(self.entry) 1742 self.addAction(self._actions['findnext']) 1743 self.addAction(self._actions['cancel']) 1744 self.setCancelEnabled(False) 1745 1746 - connect(self.entry, SIGNAL('returnPressed()'), 1747 - self.find) 1748 - connect(self.entry, SIGNAL('textEdited(const QString &)'), 1749 - self.find) 1750 + self.entry.returnPressed.connect(self.find) 1751 + self.entry.textEdited[str].connect(self.find) 1752 1753 def setVisible(self, visible=True): 1754 QuickBar.setVisible(self, visible) 1755 if visible: 1756 self.entry.setFocus()
@@ -162,25 +167,26 @@
1757 # prevent a warning in the console: 1758 # QObject::startTimer: QTimer can only be used with threads started with QThread 1759 self.entry.setCompleter(None) 1760 1761 class FindInGraphlogQuickBar(FindQuickBar): 1762 + 1763 + revision_selected = pyqtSignal([], [int]) 1764 + file_selected = pyqtSignal(str) 1765 + 1766 def __init__(self, parent): 1767 FindQuickBar.__init__(self, parent) 1768 self._findinfile_iter = None 1769 self._findinlog_iter = None 1770 self._findindesc_iter = None 1771 self._fileview = None 1772 self._headerview = None 1773 self._filter_files = None 1774 self._mode = 'diff' 1775 - connect(self, SIGNAL('find'), 1776 - self.on_find_text_changed) 1777 - connect(self, SIGNAL('findnext'), 1778 - self.on_findnext) 1779 - connect(self, SIGNAL('cancel'), 1780 - self.on_cancelsearch) 1781 + self.to_find.connect(self.on_find_text_changed) 1782 + self.to_find_next.connect(self.on_findnext) 1783 + self.canceled.connect(self.on_cancelsearch) 1784 1785 def setFilterFiles(self, files): 1786 self._filter_files = files 1787 1788 def setModel(self, model):
@@ -228,18 +234,18 @@
1789 else: 1790 yield None 1791 1792 def cancel(self): 1793 if self._actions['cancel'].isEnabled(): 1794 - self.emit(SIGNAL('cancel')) 1795 + self.canceled.emit() 1796 else: 1797 self.hide() 1798 1799 def on_cancelsearch(self, *args): 1800 self._findinlog_iter = None 1801 self.setCancelEnabled(False) 1802 - self.emit(SIGNAL('showMessage'), 'Search cancelled!', 2000) 1803 + self.message_logged.emit('Search cancelled!', 2000) 1804 1805 def on_findnext(self): 1806 """ 1807 callback called by 'Find' quicktoolbar (on findnext signal) 1808 """
@@ -278,32 +284,35 @@
1809 # when search has been cancelled 1810 return 1811 for next_find in self._findinlog_iter: 1812 if next_find is None: # not yet found, let's animate a bit the GUI 1813 if (step % 20) == 0: 1814 - self.emit(SIGNAL("showMessage"), 1815 + self.message_logged.emit( 1816 'Searching'+'.'*(step/20), 1817 -1) 1818 step += 1 1819 QtCore.QTimer.singleShot(0, partial(self.find_next_in_log, (step % 80))) 1820 else: 1821 - self.emit(SIGNAL("showMessage"), '', -1) 1822 + self.message_logged.emit('', -1) 1823 self.setCancelEnabled(False) 1824 1825 rev, filename = next_find 1826 - self.emit(SIGNAL('revisionSelected'), rev) 1827 + if rev is None: 1828 + self.revision_selected.emit() 1829 + else: 1830 + self.revision_selected[int].emit(rev) 1831 text = self.entry.text() 1832 if filename is None and self._headerview: 1833 self._findindesc_iter = self._headerview.searchString(text) 1834 self.on_findnext() 1835 else: 1836 - self.emit(SIGNAL('fileSelected'), filename) 1837 + self.file_selected.emit(tounicode(filename)) 1838 if self._fileview: 1839 self._findinfile_iter = self._fileview.searchString(text) 1840 self.on_findnext() 1841 return 1842 - self.emit(SIGNAL('showMessage'), 1843 + self.message_logged.emit( 1844 'No more matches found in repository', 1845 2000) 1846 self.setCancelEnabled(False) 1847 self._findinlog_iter = None 1848
@@ -318,11 +327,11 @@
1849 self._findindesc_iter = self._headerview.searchString(newtext) 1850 if self._fileview: 1851 self._findinfile_iter = self._fileview.searchString(newtext) 1852 if newtext.strip(): 1853 if self._findindesc_iter is None and self._findindesc_iter is None: 1854 - self.emit(SIGNAL('showMessage'), 1855 + self.message_logged.emit( 1856 'Search string not found in current diff. ' 1857 'Hit "Find next" button to start searching ' 1858 'in the repository', 1859 2000) 1860 else: