Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 2.1, 2.1.1, and 2.1.2

fileview: hoist annotate menu into HgFileView, simplify signals

The AnnotateView class is now only responsible for annotating files. Removed a
lot of redundant code.

Changeset 2654a95c0653

Parent 5786f725b649

by Steve Borho

Changes to one file · Browse files at 2654a95c0653 Showing diff from parent 5786f725b649 Diff from another changeset...

 
88
89
90
91
92
93
94
 
95
 
 
96
97
98
 
391
392
393
394
395
396
 
397
398
399
 
435
436
437
438
439
440
441
442
443
444
445
446
 
540
541
542
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
544
545
546
547
 
548
549
550
551
552
553
554
555
556
557
558
559
560
561
 
562
563
564
565
566
567
568
 
569
570
571
572
573
574
575
576
 
577
578
579
 
581
582
583
 
 
 
 
584
585
586
 
603
604
605
606
 
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
 
 
 
 
 
730
731
 
732
733
734
 
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
 
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
 
800
801
802
803
 
804
805
806
 
88
89
90
 
 
 
 
91
92
93
94
95
96
97
 
390
391
392
 
 
 
393
394
395
396
 
432
433
434
 
 
 
 
 
 
435
436
437
 
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
 
603
604
 
 
 
 
 
 
 
 
 
 
 
 
 
605
606
607
608
609
 
 
 
610
611
 
 
 
 
 
 
 
612
613
614
615
 
617
618
619
620
621
622
623
624
625
626
 
643
644
645
 
646
647
648
649
650
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651
652
653
654
655
656
 
657
658
659
660
 
672
673
674
 
675
 
676
677
 
 
 
678
 
679
680
 
 
681
682
683
684
685
 
 
686
687
 
 
 
 
 
 
 
688
689
690
 
710
711
712
 
713
714
715
716
@@ -88,11 +88,10 @@
  hbox.addWidget(self.blk)   hbox.addWidget(self.sci, 1)   - for name in ('searchRequested', 'editSelected', 'grepRequested'): - getattr(self.sci, name).connect(getattr(self, name)) - self.sci.revisionHint.connect(self.showMessage) - self.sci.sourceChanged.connect(self.sourceChanged) + self.sci.showMessage.connect(self.showMessage)   self.sci.setAnnotationEnabled(False) + self.sci.setContextMenuPolicy(Qt.CustomContextMenu) + self.sci.customContextMenuRequested.connect(self.menuRequest)     self.blk.linkScrollBar(self.sci.verticalScrollBar())   self.blk.setVisible(False) @@ -391,9 +390,7 @@
  self.sci.setText(fd.contents)   self.sci._updatemarginwidth()   if self._mode == AnnMode: - self.sci.annfile = filename - self.sci._rev = self._ctx.rev() - self.sci._updateannotation() + self.sci._updateannotation(self._ctx, filename)     # Recover the last scroll position   # Make sure that lastScrollPosition never exceeds the amount of @@ -435,12 +432,6 @@
  x, y = self.sci.getCursorPosition()   self.sci.setCursorPosition(x, y-1)   - @pyqtSlot(unicode, object) - @pyqtSlot(unicode, object, int) - def sourceChanged(self, path, rev, line=None): - if rev != self._ctx.rev() and type(rev) is int: - self.revisionSelected.emit(rev) -   @pyqtSlot(unicode, object, int)   def editSelected(self, path, rev, line):   """Open editor to show the specified file""" @@ -540,40 +531,85 @@
  def nDiffs(self):   return len(self._diffs)   + @pyqtSlot(QPoint) + def menuRequest(self, point): + menu = self.sci.createStandardContextMenu() + line = self.sci.lineAt(point) + point = self.sci.mapToGlobal(point) + if line < 0 or self._mode != AnnMode: + return menu.exec_(point) + + def setSource(path, rev, line): + self.revisionSelected.emit(rev) + self.setContext(self.repo[rev]) + self.displayFile(path, None) + self.showLine(line) + + fctx, line = self.sci._links[line] + data = [hglib.tounicode(fctx.path()), fctx.rev(), line] + + if self.sci.hasSelectedText(): + selection = self.sci.selectedText() + def sreq(**opts): + return lambda: self.grepRequested.emit(selection, opts) + def sann(): + self.searchRequested.emit(selection) + menu.addSeparator() + for name, func in [(_('Search in original revision'), + sreq(rev=fctx.rev())), + (_('Search in working revision'), + sreq(rev='.')), + (_('Search in current annotation'), sann), + (_('Search in history'), sreq(all=True))]: + def add(name, func): + action = menu.addAction(name) + action.triggered.connect(func) + add(name, func) + + def annorig(): + setSource(*data) + def editorig(): + self.editSelected(*data) + menu.addSeparator() + for name, func in [(_('Annotate originating revision'), annorig), + (_('View originating revision'), editorig)]: + def add(name, func): + action = menu.addAction(name) + action.triggered.connect(func) + add(name, func) + for pfctx in fctx.parents(): + pdata = [hglib.tounicode(pfctx.path()), pfctx.changectx().rev(), + line] + def annparent(data): + setSource(*data) + def editparent(data): + self.editSelected(*data) + for name, func in [(_('Annotate parent revision %d') % pdata[1], + annparent), + (_('View parent revision %d') % pdata[1], + editparent)]: + def add(name, func): + action = menu.addAction(name) + action.data = pdata + action.run = lambda: func(action.data) + action.triggered.connect(action.run) + add(name, func) + menu.exec_(point) +    class AnnotateView(qscilib.Scintilla):   'QScintilla widget capable of displaying annotations'   - revisionHint = pyqtSignal(QString) + showMessage = pyqtSignal(QString)   - searchRequested = pyqtSignal(QString) - """Emitted (pattern) when user request to search content""" - - editSelected = pyqtSignal(unicode, object, int) - """Emitted (path, rev, line) when user requests to open editor""" - - grepRequested = pyqtSignal(QString, dict) - """Emitted (pattern, **opts) when user request to search changelog""" - - sourceChanged = pyqtSignal(unicode, object) - """Emitted (path, rev) when the content source changed""" - - def __init__(self, repo, parent=None, **opts): + def __init__(self, repo, parent=None):   super(AnnotateView, self).__init__(parent)   self.setReadOnly(True)   self.setMarginLineNumbers(1, True)   self.setMarginType(2, qsci.TextMarginRightJustified) - self.setMouseTracking(True) - self.setContextMenuPolicy(Qt.CustomContextMenu) - self.customContextMenuRequested.connect(self.menuRequest) + self.setMouseTracking(False)   - self.repo = repo - self.repo.configChanged.connect(self.configChanged) - self.configChanged() - self._rev = None - self.annfile = None - self._annotation_enabled = bool(opts.get('annotationEnabled', False)) - + self._annotation_enabled = False   self._links = [] # by line   self._revmarkers = {} # by rev   self._lastrev = None @@ -581,6 +617,10 @@
  self._thread = AnnotateThread(self)   self._thread.finished.connect(self.fillModel)   + self.repo = repo + self.repo.configChanged.connect(self.configChanged) + self.configChanged() +   def configChanged(self):   self.setIndentationWidth(self.repo.tabwidth)   self.setTabWidth(self.repo.tabwidth) @@ -603,132 +643,18 @@
  if fctx.rev() != self._lastrev:   s = hglib.get_revision_desc(fctx,   hglib.fromunicode(self.annfile)) - self.revisionHint.emit(s) + self.showMessage.emit(s)   self._lastrev = fctx.rev()   except IndexError:   pass   - @pyqtSlot(QPoint) - def menuRequest(self, point): - menu = self.createStandardContextMenu() - line = self.lineAt(point) - point = self.mapToGlobal(point) - if line < 0 or not self.isAnnotationEnabled(): - return menu.exec_(point) - - fctx, line = self._links[line] - data = [hglib.tounicode(fctx.path()), fctx.rev(), line] - - if self.hasSelectedText(): - selection = self.selectedText() - def sreq(**opts): - return lambda: self.grepRequested.emit(selection, opts) - def sann(): - self.searchRequested.emit(selection) - menu.addSeparator() - for name, func in [(_('Search in original revision'), - sreq(rev=fctx.rev())), - (_('Search in working revision'), - sreq(rev='.')), - (_('Search in current annotation'), sann), - (_('Search in history'), sreq(all=True))]: - def add(name, func): - action = menu.addAction(name) - action.triggered.connect(func) - add(name, func) - - def annorig(): - self.setSource(*data) - def editorig(): - self.editSelected.emit(*data) - menu.addSeparator() - for name, func in [(_('Annotate originating revision'), annorig), - (_('View originating revision'), editorig)]: - def add(name, func): - action = menu.addAction(name) - action.triggered.connect(func) - add(name, func) - for pfctx in fctx.parents(): - pdata = [hglib.tounicode(pfctx.path()), pfctx.changectx().rev(), - line] - def annparent(data): - self.setSource(*data) - def editparent(data): - self.editSelected.emit(*data) - for name, func in [(_('Annotate parent revision %d') % pdata[1], - annparent), - (_('View parent revision %d') % pdata[1], - editparent)]: - def add(name, func): - action = menu.addAction(name) - action.data = pdata - action.run = lambda: func(action.data) - action.triggered.connect(action.run) - add(name, func) - menu.exec_(point) - - @property - def rev(self): - """Returns the current revision number""" - return self._rev - - @pyqtSlot(unicode, object, int) - def setSource(self, wfile, rev, line=None): - """Change the content to the specified file at rev [unicode] - - line is counted from 1. - """ - if self.annfile == wfile and self.rev == rev: - if line: - self.setCursorPosition(int(line) - 1, 0) - return - - try: - ctx = self.repo[rev] - fctx = ctx[hglib.fromunicode(wfile)] - except error.LookupError: - qtlib.ErrorMsgBox(_('Unable to annotate'), - _('%s is not found in revision %d') % (wfile, ctx.rev())) - return - - try: - if rev is None: - size = fctx.size() - else: - size = fctx._filelog.rawsize(fctx.filerev()) - except (EnvironmentError, error.LookupError), e: - self.setText(_('File or diffs not displayed: ') + \ - hglib.tounicode(str(e))) - self.error = p + hglib.tounicode(str(e)) - return - - if size > ctx._repo.maxdiff: - self.setText(_('File or diffs not displayed: ') + \ - _('File is larger than the specified max size.\n')) - else: - self._rev = ctx.rev() - self.clear() - self.annfile = wfile - if util.binary(fctx.data()): - self.setText(_('File is binary.\n')) - else: - self.setText(hglib.tounicode(fctx.data())) - if line: - self.setCursorPosition(int(line) - 1, 0) - self._updatelexer(fctx) - self._updatemarginwidth() - self.sourceChanged.emit(wfile, self._rev) - self._updateannotation() - - def _updateannotation(self): - if not self.isAnnotationEnabled() or not self.annfile: - return - ctx = self.repo[self._rev] - fctx = ctx[hglib.fromunicode(self.annfile)] - if util.binary(fctx.data()): - return + def _updateannotation(self, ctx, filename): + assert ctx.rev() is not None + assert filename in ctx + self.ctx = ctx + self.annfile = filename   self._thread.abort() - self._thread.start(fctx) + self._thread.start(ctx[filename])     @pyqtSlot()   def fillModel(self): @@ -746,35 +672,19 @@
  super(AnnotateView, self).clear()   self.clearMarginText()   self.markerDeleteAll() - self.annfile = None   - @pyqtSlot(bool)   def setAnnotationEnabled(self, enabled):   """Enable / disable annotation""" - enabled = bool(enabled) - if enabled == self.isAnnotationEnabled(): - return   self._annotation_enabled = enabled - self._updateannotation()   self._updatemarginwidth()   self.setMouseTracking(enabled) - if not self.isAnnotationEnabled(): - self.annfile = None + if not enabled:   self.markerDeleteAll()     def isAnnotationEnabled(self):   """True if annotation enabled and available""" - if self.rev is None: - return False # annotate working copy is not supported   return self._annotation_enabled   - def _updatelexer(self, fctx): - """Update the lexer according to the given file""" - lex = lexers.get_lexer(fctx.path(), hglib.tounicode(fctx.data()), self) - self.setLexer(lex) - if lex is None: - self.setFont(qtlib.getfont('fontlog').font()) -   def _updaterevmargin(self):   """Update the content of margin area showing revisions"""   s = self._margin_style @@ -800,7 +710,7 @@
    def _redefinemarkers(self):   """Redefine line markers according to the current revs""" - curdate = self.repo[self._rev].date()[0] + curdate = self.ctx.date()[0]     # make sure to colorize at least 1 year   mindate = curdate - 365 * 24 * 60 * 60