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

Merge with stable

Changeset dbe7b9b55bf1

Parents 075b6dd8684e

Parents 6a19669f2de7

by Adrian Buehlmann

Changes to 27 files · Browse files at dbe7b9b55bf1 Showing diff from parent 075b6dd8684e 6a19669f2de7 Diff from another changeset...

Show Entire File TortoiseHgOverlayServer.py Stacked
(No changes)
 
199
200
201
202
 
203
204
205
 
309
310
311
312
 
313
314
315
 
199
200
201
 
202
203
204
205
 
309
310
311
 
312
313
314
315
@@ -199,7 +199,7 @@
  return   repo.thgbackup(path)   if revertall: - commands.revert(repo.ui, repo, path) + commands.revert(repo.ui, repo, path, no_backup=True)   else:   wlock = repo.wlock()   try: @@ -309,7 +309,7 @@
  else:   repo.thgbackup(repo.wjoin(wfile))   wasadded = wfile in repo[None].added() - commands.revert(repo.ui, repo, repo.wjoin(wfile)) + commands.revert(repo.ui, repo, repo.wjoin(wfile), no_backup=True)   if wasadded:   os.unlink(repo.wjoin(wfile))   self.fileModified.emit()
 
249
250
251
252
253
254
255
256
257
258
259
260
 
 
 
 
 
261
262
263
264
265
266
267
268
269
 
 
 
 
270
271
272
 
 
 
 
 
 
 
 
 
 
 
273
274
275
 
249
250
251
 
 
 
 
 
 
 
 
 
252
253
254
255
256
257
 
 
 
 
 
 
 
 
258
259
260
261
262
 
 
263
264
265
266
267
268
269
270
271
272
273
274
275
276
@@ -249,27 +249,28 @@
  def resizeEvent(self, e):   # re-size columns the smart way: the column holding Description   # is re-sized according to the total widget size. - key = '%s/widget_width' % self.cfgname - widget_width, ok = QSettings().value(key).toInt() - if not ok: - widget_width = 0 - - if self.resized: - model = self.model() - vp_width = self.viewport().width() - total_width = stretch_col = 0 + if e.oldSize().width() != e.size().width(): + key = '%s/widget_width' % self.cfgname + widget_width, ok = QSettings().value(key).toInt() + if not ok: + widget_width = 0   - if vp_width != widget_width: - for c in range(model.columnCount(QModelIndex())): - if model._columns[c] in model._stretchs: - #save the description column - stretch_col = c - else: - #total the other widths - total_width += self.columnWidth(c) + if self.resized: + model = self.model() + vp_width = self.viewport().width() + total_width = stretch_col = 0   - width = max(vp_width - total_width, 100) - self.setColumnWidth(stretch_col, width) + if vp_width != widget_width: + for c in range(model.columnCount(QModelIndex())): + if model._columns[c] in model._stretchs: + #save the description column + stretch_col = c + else: + #total the other widths + total_width += self.columnWidth(c) + + width = max(vp_width - total_width, 100) + self.setColumnWidth(stretch_col, width)     super(HgRepoView, self).resizeEvent(e)  
 
66
67
68
 
69
70
71
 
66
67
68
69
70
71
72
@@ -66,6 +66,7 @@
  self.revset = set()   self.namedTabs = {}   self.repolen = len(repo) + self.destroyed.connect(self.repo.thginvalidate)     if repo.parents()[0].rev() == -1:   self._reload_rev = 'tip'
 
779
780
781
782
 
 
783
784
785
786
787
788
789
 
 
 
 
 
790
791
792
 
796
797
798
 
 
 
 
799
800
801
 
975
976
977
978
 
 
979
980
 
981
982
983
984
985
986
987
988
989
 
 
 
 
990
991
992
 
997
998
999
1000
 
1001
1002
1003
1004
1005
1006
1007
 
 
 
 
 
1008
1009
1010
 
 
1011
1012
1013
 
1023
1024
1025
1026
 
1027
1028
1029
 
779
780
781
 
782
783
784
785
786
787
788
789
 
790
791
792
793
794
795
796
797
 
801
802
803
804
805
806
807
808
809
810
 
984
985
986
 
987
988
989
 
990
991
992
993
994
 
 
 
 
 
995
996
997
998
999
1000
1001
 
1006
1007
1008
 
1009
1010
1011
 
 
 
 
 
1012
1013
1014
1015
1016
1017
 
 
1018
1019
1020
1021
1022
 
1032
1033
1034
 
1035
1036
1037
1038
@@ -779,14 +779,19 @@
  def refresh(self, *args):   # refresh config values   self.ini = self.loadIniFile(self.rcpath) - self.readonly = not (hasattr(self.ini, 'write') and os.access(self.fn, os.W_OK)) + self.readonly = not (hasattr(self.ini, 'write') + and os.access(self.fn, os.W_OK))   self.stack.setDisabled(self.readonly)   self.fnedit.setText(hglib.tounicode(self.fn))   for name, info, widgets in self.pages.values():   if name == 'extensions':   extsmentioned = False   for row, w in enumerate(widgets): - val = self.readCPath('extensions.' + w.opts['label']) + key = w.opts['label'] + for fullkey in (key, 'hgext.%s' % key, 'hgext/%s' % key): + val = self.readCPath('extensions.' + fullkey) + if val != None: + break   if val == None:   curvalue = False   elif len(val) and val[0] == '!': @@ -796,6 +801,10 @@
  curvalue = True   extsmentioned = True   w.setValue(curvalue) + if val == None: + w.opts['cpath'] = 'extensions.' + key + else: + w.opts['cpath'] = 'extensions.' + fullkey   if not extsmentioned:   # make sure widgets are shown properly,   # even when no extensions mentioned in the config file @@ -975,18 +984,18 @@
  if (not emitChanged) and chk.isDirty():   self.restartRequested.emit(_('Extensions'))   emitChanged = True - key = chk.opts['label'] + name = chk.opts['label'] + section, key = chk.opts['cpath'].split('.', 1)   newvalue = chk.value() - if newvalue and (key in enabledexts): + if newvalue and (name in enabledexts):   continue # unchanged   if newvalue:   self.ini.set(section, key, '')   else: - for cand in (key, 'hgext.%s' % key, 'hgext/%s' % key): - try: - del self.ini[section][cand] - except KeyError: - pass + try: + del self.ini[section][key] + except KeyError: + pass     @pyqtSlot()   def validateextensions(self): @@ -997,17 +1006,17 @@
  if chk.isChecked())   invalidexts = hglib.validateextensions(selectedexts)   - def getinival(name): + def getinival(cpath):   if section not in self.ini:   return None - for cand in (name, 'hgext.%s' % name, 'hgext/%s' % name): - try: - return self.ini[section][cand] - except KeyError: - pass + sect, key = cpath.split('.', 1) + try: + return self.ini[sect][key] + except KeyError: + pass   - def changable(name): - curval = getinival(name) + def changable(name, cpath): + curval = getinival(cpath)   if curval not in ('', None):   # enabled or unspecified, official extensions only   return False @@ -1023,7 +1032,7 @@
  allexts = hglib.allextensions()   for chk in self.pages['extensions'][2]:   name = chk.opts['label'] - chk.setEnabled(changable(name)) + chk.setEnabled(changable(name, chk.opts['cpath']))   invalmsg = invalidexts.get(name)   if invalmsg:   invalmsg = invalmsg.decode('utf-8')
 
448
449
450
 
451
452
453
 
455
456
457
 
458
459
460
 
448
449
450
451
452
453
454
 
456
457
458
459
460
461
462
@@ -448,6 +448,7 @@
  index = self.repoTabsWidget.currentIndex()   if widget.closeRepoWidget():   self.repoTabsWidget.removeTab(index) + widget.deleteLater()   self.updateMenu()     def repoTabCloseRequested(self, index): @@ -455,6 +456,7 @@
  w = tw.widget(index)   if w and w.closeRepoWidget():   tw.removeTab(index) + w.deleteLater()   self.updateMenu()     def repoTabChanged(self, index=0):
 
75
76
77
78
79
 
 
80
81
82
 
75
76
77
 
 
78
79
80
81
82
@@ -75,8 +75,8 @@
  ## tooltips   self.tips = gtklib.Tooltips()   self.tips.set_tip(frame, - _('Commit message text for new changeset that reverses the' - ' effect of the change being backed out.')) + _('Commit message text for new changeset that reverses the ' + 'effect of the change being backed out.'))     ## use English backout message option   self.eng_msg = gtk.CheckButton(_('Use English backout message'))
 
54
55
56
57
58
 
 
59
60
61
 
54
55
56
 
 
57
58
59
60
61
@@ -54,8 +54,8 @@
  def get_error_text(self):   if self.__error_text__ == None:   text = '{{{\n#!python\n' # Wrap in Bitbucket wiki preformat markers - text += _('** Please report this bug to' - ' http://bitbucket.org/tortoisehg/stable/issues\n') + text += _('** Please report this bug to ' + 'http://bitbucket.org/tortoisehg/stable/issues\n')   text += '** Mercurial version (%s). TortoiseHg version (%s)\n' % (   hglib.hgversion, version.version())   text += '** Command: %s\n' % (self.opts['cmd'])
 
76
77
78
79
 
 
 
 
80
81
82
 
133
134
135
136
 
137
138
139
 
76
77
78
 
79
80
81
82
83
84
85
 
136
137
138
 
139
140
141
142
@@ -76,7 +76,10 @@
  def _get_bugtraq_object(self):   if self.bugtr == None:   obj = CreateObject(self.guid) - self.bugtr = obj.QueryInterface(IBugTraqProvider2) + try: + self.bugtr = obj.QueryInterface(IBugTraqProvider2) + except COMError: + return None   return self.bugtr     def get_commit_message(self, parameters, logmessage): @@ -133,7 +136,7 @@
  try:   bugtr.HasOptions()   return True - except ValueError: + except (ValueError, AttributeError):   return False    
 
1116
1117
1118
1119
1120
1121
 
 
 
1122
1123
1124
1125
1126
1127
1128
1129
 
 
 
1130
1131
1132
 
1137
1138
1139
1140
1141
 
 
1142
1143
1144
 
1116
1117
1118
 
 
 
1119
1120
1121
1122
1123
1124
1125
1126
 
 
 
1127
1128
1129
1130
1131
1132
 
1137
1138
1139
 
 
1140
1141
1142
1143
1144
@@ -1116,17 +1116,17 @@
    if sumlen and len(lines[0].rstrip()) > sumlen:   resp = gdialog.Confirm(_('Confirm Commit'), [], self, - _('The summary line length of %i is greater than' - ' %i.\n\nIgnore format policy and continue' - ' commit?') % + _('The summary line length of %i is greater than ' + '%i.\n\nIgnore format policy and continue ' + 'commit?') %   (len(lines[0].rstrip()), sumlen)).run()   if resp != gtk.RESPONSE_YES:   return False   if sumlen and len(lines) > 1 and len(lines[1].strip()):   resp = gdialog.Confirm(_('Confirm Commit'), [], self, - _('The summary line is not followed by a blank' - ' line.\n\nIgnore format policy and continue' - ' commit?')).run() + _('The summary line is not followed by a blank ' + 'line.\n\nIgnore format policy and continue ' + 'commit?')).run()   if resp != gtk.RESPONSE_YES:   return False   if maxlen: @@ -1137,8 +1137,8 @@
  if errs:   resp = gdialog.Confirm(_('Confirm Commit'), [], self,   _('The following lines are over the %i-' - 'character limit: %s.\n\nIgnore format' - ' policy and continue commit?') % + 'character limit: %s.\n\nIgnore format ' + 'policy and continue commit?') %   (maxlen, ', '.join(errs))).run()   if resp != gtk.RESPONSE_YES:   return False
 
708
709
710
711
712
 
 
713
714
715
 
708
709
710
 
 
711
712
713
714
715
@@ -708,8 +708,8 @@
  spacer.set_width_chars(24)   sniplbl = gtk.Label()   snipbox.pack_start(sniplbl, False, False) - sniplbl.set_markup('<span size="large" weight="heavy"' - ' font_family="monospace">...</span>') + sniplbl.set_markup('<span size="large" weight="heavy" ' + 'font_family="monospace">...</span>')   sniplbl.set_angle(90)   snipbox.pack_start(gtk.Label())   self.csbox.pack_start(wrapbox, False, False, 2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 
 
 
 
 
 
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
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
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
735
736
737
738
739
740
741
742
743
744
745
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
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
 
 
 
 
 
 
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
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
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
735
736
737
738
739
740
741
742
743
744
745
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
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
 # datamine.py - Data Mining dialog for TortoiseHg  #  # Copyright 2008 Steve Borho <steve@borho.org>  #  # This software may be used and distributed according to the terms of the  # GNU General Public License version 2, incorporated herein by reference.    import gtk  import gobject  import os  import pango  import Queue  import threading  import re    from mercurial import util, error    from tortoisehg.util.i18n import _  from tortoisehg.util import hglib, thread2    from tortoisehg.util.colormap import AnnotateColorMap  from tortoisehg.util.colormap import AnnotateColorSaturation  from tortoisehg.hgtk.logview.treeview import TreeView as LogTreeView  from tortoisehg.hgtk.logview import treemodel as LogTreeModelModule  from tortoisehg.hgtk import gtklib, gdialog, changeset, statusbar, csinfo    # Column indexes for grep  GCOL_REVID = 0  GCOL_LINE = 1 # matched line  GCOL_DESC = 2 # utf-8, escaped summary  GCOL_PATH = 3    # Column indexes for annotation  ACOL_REVID = 0  ACOL_LINE = 1 # file line  ACOL_DESC = 2 # utf-8, escaped summary  ACOL_PATH = 3  ACOL_COLOR = 4  ACOL_USER = 5  ACOL_LNUM = 6 # line number    class DataMineDialog(gdialog.GWindow):     def get_title(self):   return _('%s - datamine') % self.get_reponame()     def get_icon(self):   return 'menurepobrowse.ico'     def parse_opts(self):   pass     def get_tbbuttons(self):   self.stop_button = self.make_toolbutton(gtk.STOCK_STOP, _('Stop'),   self.stop_current_search,   tip=_('Stop operation on current tab'))   return [   self.make_toolbutton(gtk.STOCK_FIND, _('New Search'),   self.search_clicked,   tip=_('Open new search tab')),   self.stop_button   ]     def prepare_display(self):   root = self.repo.root   cf = []   for f in self.pats:   try:   if os.path.isfile(f):   cf.append(util.canonpath(root, self.cwd, f))   elif os.path.isdir(f):   for fn in os.listdir(f):   fname = os.path.join(f, fn)   if not os.path.isfile(fname):   continue   cf.append(util.canonpath(root, self.cwd, fname))   except util.Abort:   pass   for f in cf:   self.add_annotate_page(f, '.')   if not self.notebook.get_n_pages():   self.add_search_page()   os.chdir(root)     def save_settings(self):   settings = gdialog.GWindow.save_settings(self)   return settings     def load_settings(self, settings):   gdialog.GWindow.load_settings(self, settings)   self.tabwidth = hglib.gettabwidth(self.repo.ui)     def get_body(self):   """ Initialize the Dialog. """   self.grep_cmenu = self.grep_context_menu()   self.changedesc = {}   self.newpagecount = 1   self.currev = None   vbox = gtk.VBox()   notebook = gtk.Notebook()   notebook.set_tab_pos(gtk.POS_TOP)   notebook.set_scrollable(True)   notebook.popup_enable()   notebook.show()   self.notebook = notebook   vbox.pack_start(self.notebook, True, True, 2)     self.stop_button.set_sensitive(False)     accelgroup = gtk.AccelGroup()   self.add_accel_group(accelgroup)   mod = gtklib.get_thg_modifier()   key, modifier = gtk.accelerator_parse(mod+'w')   notebook.add_accelerator('thg-close', accelgroup, key,   modifier, gtk.ACCEL_VISIBLE)   notebook.connect('thg-close', self.close_notebook)   key, modifier = gtk.accelerator_parse(mod+'n')   notebook.add_accelerator('thg-new', accelgroup, key,   modifier, gtk.ACCEL_VISIBLE)   notebook.connect('thg-new', self.new_notebook)     # status bar   hbox = gtk.HBox()   style = csinfo.labelstyle(contents=('%(shortuser)s@%(revnum)s '   '%(dateage)s', ' "%(summary)s"',), selectable=True)   self.cslabel = csinfo.create(self.repo, style=style)   hbox.pack_start(self.cslabel, False, False, 4)   self.stbar = statusbar.StatusBar()   hbox.pack_start(self.stbar)   vbox.pack_start(hbox, False, False)     return vbox     def _destroying(self, gtkobj):   self.stop_all_searches()   gdialog.GWindow._destroying(self, gtkobj)     def ann_header_context_menu(self, treeview):   m = gtklib.MenuBuilder()   m.append(_('Filename'), self.toggle_annatate_columns,   ascheck=True, args=[treeview, 2])   m.append(_('User'), self.toggle_annatate_columns,   ascheck=True, args=[treeview, 3])   menu = m.build()   menu.show_all()   return menu     def grep_context_menu(self):   m = gtklib.MenuBuilder()   m.append(_('Di_splay Change'), self.cmenu_display,   'menushowchanged.ico')   m.append(_('_Annotate File'), self.cmenu_annotate, 'menublame.ico')   m.append(_('_File History'), self.cmenu_file_log, 'menulog.ico')   m.append(_('_View File at Revision'), self.cmenu_view, gtk.STOCK_EDIT)   menu = m.build()   menu.show_all()   return menu     def annotate_context_menu(self, objs):   m = gtklib.MenuBuilder()   m.append(_('_Zoom to Change'), self.cmenu_zoom, gtk.STOCK_ZOOM_IN,   args=[objs])   m.append(_('Di_splay Change'), self.cmenu_display,   'menushowchanged.ico')   (frame, treeview, filepath, graphview) = objs   path = graphview.get_path_at_revid(int(self.currev))   filepath = graphview.get_wfile_at_path(path)   ctx = self.repo[self.currev]   fctx = ctx.filectx(filepath)   parents = fctx.parents()   if len(parents) > 0:   if len(parents) == 1:   m.append(_('_Annotate Parent'), self.cmenu_annotate_1st_parent,   'menublame.ico', args=[objs])   else:   m.append(_('_Annotate First Parent'), self.cmenu_annotate_1st_parent,   'menublame.ico', args=[objs])   m.append(_('Annotate Second Parent'), self.cmenu_annotate_2nd_parent,   'menublame.ico', args=[objs])   m.append(_('_View File at Revision'), self.cmenu_view, gtk.STOCK_EDIT)   m.append(_('_File History'), self.cmenu_file_log, 'menulog.ico')   m.append(_('_Diff to Local'), self.cmenu_local_diff)   menu = m.build()   menu.show_all()   return menu     def cmenu_zoom(self, menuitem, objs):   (frame, treeview, path, graphview) = objs   graphview.scroll_to_revision(int(self.currev))   graphview.set_revision_id(int(self.currev))     def cmenu_display(self, menuitem):   statopts = {'rev' : [self.currev] }   dlg = changeset.ChangeSet(self.ui, self.repo, self.cwd, [], statopts)   dlg.display()     def cmenu_view(self, menuitem):   self._node2 = self.currev   self._view_files([self.curpath], False)     def cmenu_annotate(self, menuitem):   self.add_annotate_page(self.curpath, self.currev)     def cmenu_annotate_1st_parent(self, menuitem, objs):   self.annotate_parent(objs, 0)     def cmenu_annotate_2nd_parent(self, menuitem, objs):   self.annotate_parent(objs, 1)     def annotate_parent(self, objs, parent_idx):   (frame, treeview, filepath, graphview) = objs   path = graphview.get_path_at_revid(int(self.currev))   filepath = graphview.get_wfile_at_path(path)   ctx = self.repo[self.currev]   fctx = ctx.filectx(filepath)   parents = fctx.parents()   parent_fctx = parents[parent_idx]   parent_revid = parent_fctx.changectx().rev()   filepath = parent_fctx.path()   # annotate file of parent rev   self.trigger_annotate(parent_revid, filepath, objs)   graphview.scroll_to_revision(int(parent_revid))   graphview.set_revision_id(int(parent_revid))     def cmenu_local_diff(self, menuitem):   opts = {'rev':[str(self.currev)], 'bundle':None}   self._do_diff([self.curpath], opts)     def cmenu_file_log(self, menuitem):   from tortoisehg.hgtk import history   dlg = history.run(self.ui, filehist=self.curpath)   dlg.display()     def grep_button_release(self, widget, event):   if event.button == 3 and not (event.state & (gtk.gdk.SHIFT_MASK |   gtk.gdk.CONTROL_MASK)):   self.grep_popup_menu(widget, event.button, event.time)   return False     def grep_popup_menu(self, treeview, button=0, time=0):   self.grep_cmenu.popup(None, None, None, button, time)   return True     def grep_thgdiff(self, treeview):   if self.currev:   self._do_diff([], {'change' : self.currev})     def grep_row_act(self, tree, path, column):   'Default action is the first entry in the context menu'   self.grep_cmenu.get_children()[0].activate()   return True     def get_rev_desc(self, rev):   if rev in self.changedesc:   return self.changedesc[rev]   ctx = self.repo[rev]   author = hglib.toutf(hglib.username(ctx.user()))   date = hglib.toutf(hglib.displaytime(ctx.date()))   text = hglib.tounicode(ctx.description()).replace(u'\0', '')   lines = text.splitlines()   summary = hglib.toutf(lines and lines[0] or '')   desc = gtklib.markup_escape_text('%s@%s %s "%s"' % \   (author, rev, date, summary))   self.changedesc[rev] = (desc, author)   return self.changedesc[rev]     def search_clicked(self, button, data):   self.add_search_page()     def create_tab_close_button(self):   button = gtk.Button()   iconBox = gtk.HBox(False, 0)   image = gtk.Image()   image.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_MENU)   gtk.Button.set_relief(button, gtk.RELIEF_NONE)   settings = gtk.Widget.get_settings(button)   (w,h) = gtk.icon_size_lookup_for_settings(settings, gtk.ICON_SIZE_MENU)   gtk.Widget.set_size_request(button, w + 4, h + 4)   image.show()   iconBox.pack_start(image, True, False, 0)   button.add(iconBox)   iconBox.show()   return button     def close_notebook(self, notebook):   if notebook.get_n_pages() <= 1:   gtklib.thgclose(self)   else:   self.close_current_page()     def new_notebook(self, notebook):   self.add_search_page()     def add_search_page(self):   frame = gtk.Frame()   frame.set_border_width(10)   vbox = gtk.VBox()     search_hbox = gtk.HBox()   regexp = gtk.Entry()   includes = gtk.Entry()   if self.cwd.startswith(self.repo.root):   try:   relpath = util.canonpath(self.repo.root, self.cwd, '.')   includes.set_text(relpath)   except util.Abort:   # Some paths inside root are invalid (.hg/*)   pass   excludes = gtk.Entry()   search = gtk.Button(_('Search'))   search_hbox.pack_start(gtk.Label(_('Regexp:')), False, False, 4)   search_hbox.pack_start(regexp, True, True, 4)   search_hbox.pack_start(gtk.Label(_('Includes:')), False, False, 4)   search_hbox.pack_start(includes, True, True, 4)   search_hbox.pack_start(gtk.Label(_('Excludes:')), False, False, 4)   search_hbox.pack_start(excludes, True, True, 4)   search_hbox.pack_start(search, False, False, 4)   self.tooltips.set_tip(search, _('Start this search'))   self.tooltips.set_tip(regexp, _('Regular expression search pattern')) - self.tooltips.set_tip(includes, _('Comma separated list of' - ' inclusion patterns. By default, the entire repository' - ' is searched.')) - self.tooltips.set_tip(excludes, _('Comma separated list of' - ' exclusion patterns. Exclusion patterns are applied' - ' after inclusion patterns.')) + self.tooltips.set_tip(includes, _('Comma separated list of ' + 'inclusion patterns. By default, the entire repository ' + 'is searched.')) + self.tooltips.set_tip(excludes, _('Comma separated list of ' + 'exclusion patterns. Exclusion patterns are applied ' + 'after inclusion patterns.'))   vbox.pack_start(search_hbox, False, False, 4)     hbox = gtk.HBox()   follow = gtk.CheckButton(_('Follow copies and renames'))   ignorecase = gtk.CheckButton(_('Ignore case'))   linenum = gtk.CheckButton(_('Show line numbers'))   showall = gtk.CheckButton(_('Show all matching revisions'))   hbox.pack_start(follow, False, False, 4)   hbox.pack_start(ignorecase, False, False, 4)   hbox.pack_start(linenum, False, False, 4)   hbox.pack_start(showall, False, False, 4)   vbox.pack_start(hbox, False, False, 4)     treeview = gtk.TreeView()   treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)   treeview.set_rules_hint(True)   treeview.set_property('fixed-height-mode', True)   treeview.connect("cursor-changed", self.grep_selection_changed)   treeview.connect('button-release-event', self.grep_button_release)   treeview.connect('popup-menu', self.grep_popup_menu)   treeview.connect('row-activated', self.grep_row_act)     accelgroup = gtk.AccelGroup()   self.add_accel_group(accelgroup)   mod = gtklib.get_thg_modifier()   key, modifier = gtk.accelerator_parse(mod+'d')   treeview.add_accelerator('thg-diff', accelgroup, key,   modifier, gtk.ACCEL_VISIBLE)   treeview.connect('thg-diff', self.grep_thgdiff)     results = gtk.ListStore(str, # revision id   str, # matched line (utf-8)   str, # description (utf-8, escaped)   str) # file path (utf-8)   treeview.set_model(results)   treeview.set_search_equal_func(self.search_in_grep)   for title, width, ttype, col, emode in (   (_('Rev'), 10, 'text', GCOL_REVID, pango.ELLIPSIZE_NONE),   (_('File'), 25, 'text', GCOL_PATH, pango.ELLIPSIZE_START),   (_('Matches'), 80, 'markup', GCOL_LINE, pango.ELLIPSIZE_END)):   cell = gtk.CellRendererText()   cell.set_property('width-chars', width)   cell.set_property('ellipsize', emode)   cell.set_property('family', 'Monospace')   column = gtk.TreeViewColumn(title)   column.set_resizable(True)   column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)   column.set_fixed_width(cell.get_size(treeview)[2])   column.pack_start(cell, expand=True)   column.add_attribute(cell, ttype, col)   treeview.append_column(column)   if hasattr(treeview, 'set_tooltip_column'):   treeview.set_tooltip_column(GCOL_DESC)   scroller = gtk.ScrolledWindow()   scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)   scroller.add(treeview)   vbox.pack_start(scroller, True, True)   frame.add(vbox)   frame.show_all()     hbox = gtk.HBox()   lbl = gtk.Label(_('Search %d') % self.newpagecount)   close = self.create_tab_close_button()   close.connect('clicked', self.close_page, frame)   hbox.pack_start(lbl, True, True, 2)   hbox.pack_start(close, False, False)   hbox.show_all()   num = self.notebook.append_page(frame, hbox)     self.newpagecount += 1   objs = (treeview.get_model(), frame, regexp, follow, ignorecase,   excludes, includes, linenum, showall, search_hbox)   # Clicking 'search' or hitting Enter in any text entry triggers search   search.connect('clicked', self.trigger_search, objs)   regexp.connect('activate', self.trigger_search, objs)   includes.connect('activate', self.trigger_search, objs)   excludes.connect('activate', self.trigger_search, objs)   # Includes/excludes must disable following copies   objs = (includes, excludes, follow)   includes.connect('changed', self.update_following_possible, objs)   excludes.connect('changed', self.update_following_possible, objs)   self.update_following_possible(includes, objs)     if hasattr(self.notebook, 'set_tab_reorderable'):   self.notebook.set_tab_reorderable(frame, True)   self.notebook.set_current_page(num)   regexp.grab_focus()     def search_in_grep(self, model, column, key, iter):   """Searches all fields shown in the tree when the user hits crtr+f,   not just the ones that are set via tree.set_search_column.   Case insensitive   """   key = key.lower()   for col in (GCOL_PATH, GCOL_LINE):   if key in model.get_value(iter, col).lower():   return False   return True     def trigger_search(self, button, objs):   (model, frame, regexp, follow, ignorecase,   excludes, includes, linenum, showall, search_hbox) = objs   retext = regexp.get_text()   if not retext:   gdialog.Prompt(_('No regular expression given'),   _('You must provide a search expression'), self).run()   regexp.grab_focus()   return   try:   re.compile(retext)   except re.error, e:   gdialog.Prompt(_('Invalid regular expression'),   _('Error: %s') % str(e), self).run()   regexp.grab_focus()   return     q = Queue.Queue()   args = [q, 'grep']   if follow.get_active(): args.append('--follow')   if ignorecase.get_active(): args.append('--ignore-case')   if linenum.get_active(): args.append('--line-number')   if showall.get_active(): args.append('--all')   incs = [x.strip() for x in includes.get_text().split(',')]   excs = [x.strip() for x in excludes.get_text().split(',')]   for i in incs:   if i: args.extend(['-I', i])   for x in excs:   if x: args.extend(['-X', x])   args.append(retext)     def threadfunc(q, *args):   try:   hglib.hgcmd_toq(q, True, args)   except (util.Abort, error.LookupError), e:   self.stbar.set_text(_('Abort: %s') % str(e))     thread = thread2.Thread(target=threadfunc, args=args)   thread.start()   frame._mythread = thread   self.stop_button.set_sensitive(True)     model.clear()   search_hbox.set_sensitive(False)   self.stbar.begin(msg='hg ' + ' '.join(args[2:]))     hbox = gtk.HBox()   lbl = gtk.Label(_('Search "%s"') % retext.split()[0])   close = self.create_tab_close_button()   close.connect('clicked', self.close_page, frame)   hbox.pack_start(lbl, True, True, 2)   hbox.pack_start(close, False, False)   hbox.show_all()   self.notebook.set_tab_label(frame, hbox)     gobject.timeout_add(50, self.grep_wait, thread, q, model,   search_hbox, regexp, frame)     def grep_wait(self, thread, q, model, search_hbox, regexp, frame):   """   Handle all the messages currently in the queue (if any).   """   text = ''   while q.qsize():   data, label = q.get(0)   data = gtklib.markup_escape_text(hglib.toutf(data))   if label == 'grep.match':   text += '<span foreground="red"><b>%s</b></span>' % data   else:   text += data     for line in text.splitlines():   try:   (path, revid, text) = line.split(':', 2)   desc, user = self.get_rev_desc(long(revid))   except ValueError:   continue   if self.tabwidth:   text = text.expandtabs(self.tabwidth)   model.append((revid, text, desc, hglib.toutf(path)))   if thread.isAlive():   return True   else:   if threading.activeCount() == 1:   self.stop_button.set_sensitive(False)   frame._mythread = None   search_hbox.set_sensitive(True)   regexp.grab_focus()   self.stbar.end()   return False     def grep_selection_changed(self, treeview):   """   Callback for when the user selects grep output.   """   (path, focus) = treeview.get_cursor()   model = treeview.get_model()   if path is not None and model is not None:   iter = model.get_iter(path)   self.currev = model[iter][GCOL_REVID]   self.curpath = hglib.fromutf(model[iter][GCOL_PATH])   self.cslabel.update(model[iter][GCOL_REVID])     def close_current_page(self):   num = self.notebook.get_current_page()   if num != -1 and self.notebook.get_n_pages():   self.notebook.remove_page(num)     def stop_current_search(self, button, widget):   num = self.notebook.get_current_page()   frame = self.notebook.get_nth_page(num)   self.stop_search(frame)     def stop_all_searches(self):   for num in xrange(self.notebook.get_n_pages()):   frame = self.notebook.get_nth_page(num)   self.stop_search(frame)     def stop_search(self, frame):   if getattr(frame, '_mythread', None):   if frame._mythread.isAlive():   try:   frame._mythread.terminate()   frame._mythread.join()   except (threading.ThreadError, ValueError):   pass   frame._mythread = None     def close_page(self, button, widget):   '''Close page button has been pressed'''   num = self.notebook.page_num(widget)   if num != -1:   self.notebook.remove_page(num)   if self.notebook.get_n_pages() < 1:   self.newpagecount = 1   self.add_search_page()     def add_header_context_menu(self, col, menu):   lb = gtk.Label(col.get_title())   lb.show()   col.set_widget(lb)   wgt = lb.get_parent()   while wgt:   if type(wgt) == gtk.Button:   wgt.connect("button-press-event",   self.tree_header_button_press, menu)   break   wgt = wgt.get_parent()     def tree_header_button_press(self, widget, event, menu):   if event.button == 3:   menu.popup(None, None, None, event.button, event.time)   return True   return False     def update_following_possible(self, widget, objs):   (includes, excludes, follow) = objs   allow = not includes.get_text() and not excludes.get_text()   if not allow:   follow.set_active(False)   follow.set_sensitive(allow)     def add_annotate_page(self, path, revid):   '''   Add new annotation page to notebook. Start scan of   file 'path' revision history, start annotate of supplied   revision 'revid'.   '''   if revid == '.':   ctx = self.repo.parents()[0]   try:   fctx = ctx.filectx(path)   except error.LookupError:   gdialog.Prompt(_('File is unrevisioned'),   _('Unable to annotate ') + path, self).run()   return   rev = fctx.filelog().linkrev(fctx.filerev())   revid = str(rev)   else:   rev = long(revid)     frame = gtk.Frame()   frame.set_border_width(10)   vbox = gtk.VBox()     graphopts = { 'date': None, 'no_merges':False, 'only_merges':False,   'keyword':[], 'branch':None, 'pats':[], 'revrange':[],   'revlist':[], 'noheads':False, 'orig-tip':len(self.repo),   'branch-view':False, 'rev':[], 'npreviews':0 }   graphopts['filehist'] = path     # File log revision graph   graphview = LogTreeView(self.repo, 5000)   graphview.set_property('rev-column-visible', True)   graphview.set_property('msg-column-visible', True)   graphview.set_property('user-column-visible', True)   graphview.set_property('age-column-visible', True)   graphview.set_columns(['graph', 'rev', 'msg', 'user', 'age'])   graphview.connect('revisions-loaded', self.revisions_loaded, rev)   graphview.refresh(True, [path], graphopts)     # Annotation text tree view   treeview = gtk.TreeView()   treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)   treeview.set_property('fixed-height-mode', True)   treeview.set_border_width(0)     accelgroup = gtk.AccelGroup()   self.add_accel_group(accelgroup)   mod = gtklib.get_thg_modifier()   key, modifier = gtk.accelerator_parse(mod+'d')   treeview.add_accelerator('thg-diff', accelgroup, key,   modifier, gtk.ACCEL_VISIBLE)   treeview.connect('thg-diff', self.annotate_thgdiff)     results = gtk.ListStore(str, # revision id   str, # file line (utf-8)   str, # description (utf-8, escaped)   str, # file path (utf-8)   str, # color   str, # author (utf-8)   str) # line number   treeview.set_model(results)   treeview.set_search_equal_func(self.search_in_file)     context_menu = self.ann_header_context_menu(treeview)   for title, width, col, emode, visible in (   (_('Line'), 8, ACOL_LNUM, pango.ELLIPSIZE_NONE, True),   (_('Rev'), 10, ACOL_REVID, pango.ELLIPSIZE_NONE, True),   (_('File'), 15, ACOL_PATH, pango.ELLIPSIZE_START, False),   (_('User'), 15, ACOL_USER, pango.ELLIPSIZE_END, False),   (_('Source'), 80, ACOL_LINE, pango.ELLIPSIZE_END, True)):   cell = gtk.CellRendererText()   cell.set_property('width-chars', width)   cell.set_property('ellipsize', emode)   cell.set_property('family', 'Monospace')   column = gtk.TreeViewColumn(title)   column.set_resizable(True)   column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)   column.set_fixed_width(cell.get_size(treeview)[2])   column.pack_start(cell, expand=True)   column.add_attribute(cell, 'text', col)   column.add_attribute(cell, 'background', ACOL_COLOR)   column.set_visible(visible)   treeview.append_column(column)   self.add_header_context_menu(column, context_menu)   treeview.set_headers_clickable(True)   if hasattr(treeview, 'set_tooltip_column'):   treeview.set_tooltip_column(ACOL_DESC)   results.path = path   results.rev = revid   scroller = gtk.ScrolledWindow()   scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)   scroller.add(treeview)     vpaned = gtk.VPaned()   vpaned.pack1(graphview, True, True)   vpaned.pack2(scroller, True, True)   vbox.pack_start(vpaned, True, True)   frame.add(vbox)   frame.show_all()     hbox = gtk.HBox()   lbl = gtk.Label(hglib.toutf(os.path.basename(path) + '@' + revid))   close = self.create_tab_close_button()   close.connect('clicked', self.close_page, frame)   hbox.pack_start(lbl, True, True, 2)   hbox.pack_start(close, False, False)   hbox.show_all()   num = self.notebook.append_page_menu(frame,   hbox, gtk.Label(hglib.toutf(path + '@' + revid)))     if hasattr(self.notebook, 'set_tab_reorderable'):   self.notebook.set_tab_reorderable(frame, True)   self.notebook.set_current_page(num)     graphview.connect('revision-selected', self.log_selection_changed, path)     objs = (frame, treeview, path, graphview)   graphview.treeview.connect('row-activated', self.log_activate, objs)   graphview.treeview.connect('button-release-event',   self.ann_button_release, objs)   graphview.treeview.connect('popup-menu', self.ann_popup_menu, objs)     treeview.connect("cursor-changed", self.ann_selection_changed)   treeview.connect('button-release-event', self.ann_button_release, objs)   treeview.connect('popup-menu', self.ann_popup_menu, objs)   treeview.connect('row-activated', self.ann_row_act, objs)     self.stbar.begin(msg=_('Loading history...'))     def search_in_file(self, model, column, key, iter):   """Searches all fields shown in the tree when the user hits crtr+f,   not just the ones that are set via tree.set_search_column.   Case insensitive   """   key = key.lower()   for col in (ACOL_USER, ACOL_LINE):   if key in model.get_value(iter, col).lower():   return False   return True     def annotate_thgdiff(self, treeview):   self._do_diff([], {'change' : self.currev})     def toggle_annatate_columns(self, button, treeview, col):   b = button.get_active()   treeview.get_column(col).set_visible(b)     def log_selection_changed(self, graphview, path):   treeview = graphview.treeview   (model, paths) = treeview.get_selection().get_selected_rows()   if not paths:   return   revid = graphview.get_revid_at_path(paths[0])   self.currev = str(revid)   wfile = graphview.get_wfile_at_path(paths[0])   if wfile:   self.curpath = wfile     def log_activate(self, treeview, path, column, objs):   (frame, treeview, file, graphview) = objs   rev = graphview.get_revid_at_path(path)   wfile = graphview.get_wfile_at_path(path)   self.trigger_annotate(rev, wfile, objs)     def revisions_loaded(self, graphview, rev):   self.stbar.end()   graphview.set_revision_id(rev)   treeview = graphview.treeview   path, column = treeview.get_cursor()   # It's possible that the requested change was not found in the   # file's filelog history. In that case, no row will be   # selected.   if path != None and column != None:   treeview.row_activated(path, column)     def trigger_annotate(self, rev, path, objs):   '''   User has selected a file revision to annotate. Trigger a   background thread to perform the annotation. Disable the select   button until this operation is complete.   '''   def threadfunc(q, *args):   try:   hglib.hgcmd_toq(q, False, args)   except (util.Abort, error.LookupError), e:   self.stbar.set_text(_('Abort: %s') % str(e))     (frame, treeview, origpath, graphview) = objs   q = Queue.Queue()   # Use short -f here because it's meaning has changed, it used   # to be --follow but now it means --file. We want either.   # Replace -f with --file when support for hg-1.4 is dropped   args = [q, 'annotate', '-f', '--number', '--rev', str(rev),   'path:'+path]   thread = thread2.Thread(target=threadfunc, args=args)   thread.start()   frame._mythread = thread   self.stop_button.set_sensitive(True)     # date of selected revision   ctx = self.repo[long(rev)]   curdate = ctx.date()[0]   colormap = AnnotateColorSaturation()     model, rows = treeview.get_selection().get_selected_rows()   model.clear()   self.stbar.begin(msg=hglib.toutf('hg ' + ' '.join(args[2:])))     hbox = gtk.HBox()   lbl = gtk.Label(hglib.toutf(os.path.basename(path) + '@' + str(rev)))   close = self.create_tab_close_button()   close.connect('clicked', self.close_page, frame)   hbox.pack_start(lbl, True, True, 2)   hbox.pack_start(close, False, False)   hbox.show_all()   self.notebook.set_tab_label(frame, hbox)     gobject.timeout_add(50, self.annotate_wait, thread, q, treeview,   curdate, colormap, frame, rows)     def annotate_wait(self, thread, q, tview, curdate, colormap, frame, rows):   """   Handle all the messages currently in the queue (if any).   """   model = tview.get_model()   while q.qsize():   line = q.get(0).rstrip('\r\n')   try:   (revpath, text) = line.split(':', 1)   revid, path = revpath.lstrip().split(' ', 1)   rowrev = long(revid)   except ValueError:   continue   desc, user = self.get_rev_desc(rowrev)   ctx = self.repo[rowrev]   color = colormap.get_color(ctx, curdate)   if self.tabwidth:   text = text.expandtabs(self.tabwidth)   model.append((revid, hglib.toutf(text[:512]), desc,   hglib.toutf(path.strip()), color, user, len(model)+1))   if thread.isAlive():   return True   else:   if threading.activeCount() == 1:   self.stop_button.set_sensitive(False)   if rows:   tview.get_selection().select_path(rows[0])   tview.scroll_to_cell(rows[0], use_align=True, row_align=0.5)   tview.grab_focus()   frame._mythread = None   self.stbar.end()   return False     def ann_selection_changed(self, treeview):   """   User selected line of annotate output, describe revision   responsible for this line in the status bar   """   (path, focus) = treeview.get_cursor()   model = treeview.get_model()   if path is not None and model is not None:   anniter = model.get_iter(path)   self.currev = model[anniter][ACOL_REVID]   self.path = model.path   self.cslabel.update(model[anniter][ACOL_REVID])     def ann_button_release(self, widget, event, objs):   if event.button == 3 and not (event.state & (gtk.gdk.SHIFT_MASK |   gtk.gdk.CONTROL_MASK)):   self.ann_popup_menu(widget, event.button, event.time, objs)   return False     def ann_popup_menu(self, treeview, button, time, objs):   ann_cmenu = self.annotate_context_menu(objs)   ann_cmenu.popup(None, None, None, button, time)   return True     def ann_row_act(self, tree, path, column, objs):   ann_cmenu = self.annotate_context_menu(objs)   ann_cmenu.get_children()[0].activate()    def run(ui, *pats, **opts):   cmdoptions = {   'follow':False, 'follow-first':False, 'copies':False, 'keyword':[],   'limit':0, 'rev':[], 'removed':False, 'no_merges':False, 'date':None,   'only_merges':None, 'prune':[], 'git':False, 'verbose':False,   'include':[], 'exclude':[]   }   return DataMineDialog(ui, None, None, pats, cmdoptions)
 
235
236
237
238
 
 
239
240
241
 
235
236
237
 
238
239
240
241
242
@@ -235,7 +235,8 @@
  unkmodel = self.unktree.get_model()   while q.qsize():   wfile = q.get(0) - unkmodel.append( [wfile, hglib.toutf(wfile)] ) + if unkmodel is not None: + unkmodel.append( [wfile, hglib.toutf(wfile)] )   return thread.isAlive()     def save_settings(self):
 
98
99
100
101
102
103
 
 
 
104
105
106
107
108
109
110
111
 
 
 
112
113
114
115
116
117
118
119
 
 
 
120
121
122
123
124
125
126
127
128
 
 
 
129
130
131
132
133
 
 
134
135
136
 
229
230
231
232
233
234
235
236
237
 
 
 
 
 
 
238
239
240
 
98
99
100
 
 
 
101
102
103
104
105
106
107
108
 
 
 
109
110
111
112
113
114
115
116
 
 
 
117
118
119
120
121
122
123
124
125
 
 
 
126
127
128
129
130
131
 
 
132
133
134
135
136
 
229
230
231
 
 
 
 
 
 
232
233
234
235
236
237
238
239
240
@@ -98,39 +98,39 @@
  self._normal = gtk.RadioButton(None, _('Send changesets as Hg patches'))   table.add_row(self._normal)   self.tips.set_tip(self._normal, - _('Hg patches (as generated by export command) are compatible' - ' with most patch programs. They include a header which' - ' contains the most important changeset metadata.')) + _('Hg patches (as generated by export command) are compatible ' + 'with most patch programs. They include a header which ' + 'contains the most important changeset metadata.'))     self._git = gtk.RadioButton(self._normal,   _('Use extended (git) patch format'))   table.add_row(self._git)   self.tips.set_tip(self._git, - _('Git patches can describe binary files, copies, and' - ' permission changes, but recipients may not be able to' - ' use them if they are not using git or Mercurial.')) + _('Git patches can describe binary files, copies, and ' + 'permission changes, but recipients may not be able to ' + 'use them if they are not using git or Mercurial.'))     self._plain = gtk.RadioButton(self._normal,   _('Plain, do not prepend Hg header'))   table.add_row(self._plain)   self.tips.set_tip(self._plain, - _('Stripping Mercurial header removes username and parent' - ' information. Only useful if recipient is not using' - ' Mercurial (and does not like to see the headers).')) + _('Stripping Mercurial header removes username and parent ' + 'information. Only useful if recipient is not using ' + 'Mercurial (and does not like to see the headers).'))     self._bundle = gtk.RadioButton(self._normal,   _('Send single binary bundle, not patches'))   table.add_row(self._bundle)   if revargs[0] in ('--outgoing', '-o'):   self.tips.set_tip(self._bundle, - _('Bundles store complete changesets in binary form.' - ' Upstream users can pull from them. This is the safest' - ' way to send changes to recipient Mercurial users.')) + _('Bundles store complete changesets in binary form. ' + 'Upstream users can pull from them. This is the safest ' + 'way to send changes to recipient Mercurial users.'))   else:   self._bundle.set_sensitive(False)   self.tips.set_tip(self._bundle, - _('This feature is only available when sending outgoing' - ' changesets. It is not applicable with revision ranges.')) + _('This feature is only available when sending outgoing ' + 'changesets. It is not applicable with revision ranges.'))     self._attach = gtk.CheckButton(_('attach'))   self.tips.set_tip(self._attach, @@ -229,12 +229,12 @@
  self._frombox.child.set_text(hglib.fromutf(getfromaddr(repo.ui)))   self._subjbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'subject', '')))   self.tips.set_tip(self._eventbox, - _('Patch series description is sent in initial summary' - ' email with [PATCH 0 of N] subject. It should describe' - ' the effects of the entire patch series. When emailing' - ' a bundle, these fields make up the message subject and' - ' body. Flags is a comma separated list of tags' - ' which are inserted into the message subject prefix.') + _('Patch series description is sent in initial summary ' + 'email with [PATCH 0 of N] subject. It should describe ' + 'the effects of the entire patch series. When emailing ' + 'a bundle, these fields make up the message subject and ' + 'body. Flags is a comma separated list of tags ' + 'which are inserted into the message subject prefix.')   )   gtklib.addspellcheck(self.descview, self.repo.ui)   fill_history(history, self._tolist, 'email.to')
 
224
225
226
227
 
 
 
 
 
 
228
229
230
 
252
253
254
255
 
256
257
258
 
224
225
226
 
227
228
229
230
231
232
233
234
235
 
257
258
259
 
260
261
262
263
@@ -224,7 +224,12 @@
  def refresh(self):   hglib.invalidaterepo(self.repo)   matcher = match.always(self.repo.root, self.repo.root) - unknown = self.repo.status(match=matcher, unknown=True)[4] + try: + unknown = self.repo.status(match=matcher, unknown=True)[4] + except (EnvironmentError, util.Abort), inst: + gdialog.Prompt(_('Error while reading status'), + hglib.toutf(str(inst)), self).run() + return   self.unkmodel.clear()   for u in unknown:   self.unkmodel.append([hglib.toutf(u), u]) @@ -252,7 +257,7 @@
  createmode=None)   f.writelines(out)   f.rename() - except IOError, e: + except EnvironmentError, e:   dialog.error_dialog(self, _('Unable to write .hgignore file'),   hglib.tounicode(str(e)))   shlib.shell_notify([self.ignorefile])
 
797
798
799
800
801
 
 
802
803
804
 
797
798
799
 
 
800
801
802
803
804
@@ -797,8 +797,8 @@
  [('', 'delay', None, _('wait until the second ticks over')),   ('n', 'notify', [], _('notify the shell for paths given')),   ('', 'remove', None, _('remove the status cache')), - ('s', 'show', None, _('show the contents of the' - ' status cache (no update)')), + ('s', 'show', None, _('show the contents of the ' + 'status cache (no update)')),   ('', 'all', None, _('udpate all repos in current dir')) ],   _('hgtk thgstatus [OPTION]')),   "^update|checkout|co": (update,
 
194
195
196
197
198
 
 
199
200
201
 
213
214
215
216
217
 
 
218
219
220
 
194
195
196
 
 
197
198
199
200
201
 
213
214
215
 
 
216
217
218
219
220
@@ -194,8 +194,8 @@
  def before_close(self):   if len(self.repo.parents()) == 2:   ret = gdialog.Confirm(_('Confirm Exit'), [], self, - _('To complete merging, you need to commit' - ' merged files in working directory.\n\n' + _('To complete merging, you need to commit ' + 'merged files in working directory.\n\n'   'Do you want to exit?')).run()   if ret != gtk.RESPONSE_YES:   return False @@ -213,8 +213,8 @@
  # '.' is safer than self.localrev, in case the user has   # pulled a fast one on us and updated from the CLI   ret = gdialog.Confirm(_('Confirm Discard Changes'), [], self, - _('The changes from revision %s and all unmerged parents' - ' will be discarded.\n\n' + _('The changes from revision %s and all unmerged parents ' + 'will be discarded.\n\n'   'Are you sure this is what you want to do?')   % (self.otherframe.get_data('revid'))).run()   if ret != gtk.RESPONSE_YES:
 
56
57
58
59
60
 
 
61
62
63
 
56
57
58
 
 
59
60
61
62
63
@@ -56,8 +56,8 @@
  self._toolbutton(gtk.STOCK_UNDO,   _('Rollback'),   self._rollback_clicked, - tip=_('Rollback (undo) last transaction to' - ' repository (pull, commit, etc)')), + tip=_('Rollback (undo) last transaction to ' + 'repository (pull, commit, etc)')),   gtk.SeparatorToolItem(),   self._toolbutton(gtk.STOCK_CLEAR,   _('Recover'),
 
365
366
367
368
369
 
 
370
371
372
 
365
366
367
 
 
368
369
370
371
372
@@ -365,8 +365,8 @@
  _('name to show in web pages (default: working dir)')),   ('', 'web-conf', '',   _('name of the hgweb config file (serve more than one repository)')), - ('', 'webdir-conf', '', _('name of the webdir config file' - ' (DEPRECATED)')), + ('', 'webdir-conf', '', _('name of the webdir config file ' + '(DEPRECATED)')),   ('', 'pid-file', '', _('name of file to write process ID to')),   ('', 'stdio', None, _('for remote clients')),   ('t', 'templates', '', _('web templates to use')),
 
23
24
25
26
27
28
29
 
149
150
151
152
 
153
154
155
 
189
190
191
192
 
193
194
195
 
208
209
210
211
212
 
 
213
214
215
 
23
24
25
 
26
27
28
 
148
149
150
 
151
152
153
154
 
188
189
190
 
191
192
193
194
 
207
208
209
 
 
210
211
212
213
214
@@ -23,7 +23,6 @@
    self.set_default_size(400, -1)   self.set_title(_('TortoiseHg Shell Configuration')) - self.setWindowIcon(qtlib.geticon('detect_rename'))     okay = gtk.Button(_('OK'))   cancel = gtk.Button(_('Cancel')) @@ -149,7 +148,7 @@
  hbox = gtk.HBox()   tvbox.pack_start(hbox, False, False, 2)   hbox.pack_start(gtk.Label( - _('Warning: affects all Tortoises, logoff required after change')), + _('Warning: affects all Tortoises, logoff required after change')),   False, False, 2)     hbox = gtk.HBox() @@ -189,7 +188,7 @@
  hbox = gtk.HBox()   tvbox.pack_start(hbox, False, False, 2)   hbox.pack_start(gtk.Label( - _('*: not used by TortoiseHg')), + _('*: not used by TortoiseHg')),   False, False, 2)     ## Taskbar group @@ -208,8 +207,8 @@
  # Tooltips   tips = gtklib.Tooltips()   - tooltip = _('Do not show menu items on unversioned folders' - ' (use shift + click to override)') + tooltip = _('Do not show menu items on unversioned folders ' + '(use shift + click to override)')   tips.set_tip(self.hide_context_menu, tooltip)   tooltip = _('Show overlay icons in Mercurial repositories')   tips.set_tip(self.ovenable, tooltip)
 
56
57
58
59
60
 
 
61
62
63
64
65
 
 
66
67
68
69
70
71
 
72
73
74
75
76
 
 
77
78
79
80
81
 
 
82
83
84
 
172
173
174
175
176
 
 
177
178
179
 
192
193
194
195
196
 
 
 
197
198
199
 
202
203
204
205
206
 
 
207
208
209
 
56
57
58
 
 
59
60
61
62
63
 
 
64
65
66
67
68
69
70
 
71
72
73
74
 
 
75
76
77
78
79
 
 
80
81
82
83
84
 
172
173
174
 
 
175
176
177
178
179
 
192
193
194
 
 
195
196
197
198
199
200
 
203
204
205
 
 
206
207
208
209
210
@@ -56,29 +56,29 @@
  self.toolbutton(gtk.STOCK_GO_DOWN,   _('Incoming'),   self.incoming_clicked, - tip=_('Display changes that can be pulled' - ' from selected repository')), + tip=_('Display changes that can be pulled ' + 'from selected repository')),   self.toolbutton(gtk.STOCK_GOTO_BOTTOM,   _(' Pull '),   self.pull_clicked, - tip=_('Pull changes from selected' - ' repository')), + tip=_('Pull changes from selected ' + 'repository')),   gtk.SeparatorToolItem(),   self.toolbutton(gtk.STOCK_GO_UP,   _('Outgoing'),   self.outgoing_clicked,   tip=_('Display local changes that will be ' - ' pushed to selected repository')), + 'pushed to selected repository')),   self.toolbutton(gtk.STOCK_GOTO_TOP,   _('Push'),   self.push_clicked, - tip=_('Push local changes to selected' - ' repository')), + tip=_('Push local changes to selected ' + 'repository')),   self.toolbutton(gtk.STOCK_GOTO_LAST,   _('Email'),   self.email_clicked, - tip=_('Email local outgoing changes to' - ' one or more recipients')), + tip=_('Email local outgoing changes to ' + 'one or more recipients')),   self.toolbutton(gtk.STOCK_UNDO,   _('Shelve'),   self.shelve_clicked, @@ -172,8 +172,8 @@
  ## checkbox options   chkopthbox = gtk.HBox()   self.force = gtk.CheckButton(_('Force pull or push')) - self.tips.set_tip(self.force, _('Run even when remote repository' - ' is unrelated.')) + self.tips.set_tip(self.force, + _('Run even when remote repository is unrelated.'))   self.newbranch = gtk.CheckButton(_('Push new branch'))   self.tips.set_tip(self.newbranch, _('Allow pushing a new branch'))   self.use_proxy = gtk.CheckButton(_('Use proxy server')) @@ -192,8 +192,9 @@
  revhbox.pack_start(self.reventry, True, True, 2)   reveventbox = gtk.EventBox()   reveventbox.add(revhbox) - self.tips.set_tip(reveventbox, _('A specific revision up to which you' - ' would like to push or pull.')) + self.tips.set_tip(reveventbox, + _('A specific revision up to which you ' + 'would like to push or pull.'))     ## remote command option   cmdhbox = gtk.HBox() @@ -202,8 +203,8 @@
  cmdhbox.pack_start(self.cmdentry, True, True, 2)   cmdeventbox = gtk.EventBox()   cmdeventbox.add(cmdhbox) - self.tips.set_tip(cmdeventbox, _('Name of hg executable on remote' - ' machine.')) + self.tips.set_tip(cmdeventbox, + _('Name of hg executable on remote machine.'))     revvbox = gtk.VBox()   revvbox.pack_start(chkopthbox, False, False, 8)
 
43
44
45
46
47
48
49
50
51
 
 
 
 
 
 
52
53
54
55
56
 
 
 
 
57
58
59
60
61
62
 
 
 
63
64
65
66
 
 
 
67
68
69
70
 
 
71
72
73
74
 
 
 
75
76
77
 
 
78
79
80
 
 
81
82
83
 
 
84
85
86
87
 
 
88
89
90
91
92
93
94
95
96
 
 
 
 
97
98
99
100
101
102
 
 
 
 
 
103
104
105
 
 
106
107
108
 
 
109
110
111
112
 
 
 
113
114
115
116
 
 
 
117
118
119
120
121
 
 
 
 
122
123
124
125
 
 
 
126
127
128
129
130
131
132
133
134
 
 
 
 
135
136
137
138
 
 
 
139
140
141
142
 
 
 
143
144
145
146
 
 
 
147
148
149
150
151
152
153
 
 
 
 
 
 
154
155
156
157
158
 
 
 
 
159
160
161
162
163
164
 
 
165
166
167
 
 
168
169
170
171
172
173
174
175
176
 
 
 
177
178
179
180
181
182
 
 
183
184
185
 
 
186
187
188
 
 
189
190
191
192
193
194
 
 
195
196
197
198
 
 
199
200
201
 
 
202
203
204
205
206
207
208
209
210
211
212
213
 
 
 
 
 
 
 
214
215
216
217
218
219
220
 
 
 
 
 
 
221
222
223
224
225
226
227
228
 
 
229
230
231
 
 
232
233
234
 
237
238
239
240
241
 
 
242
243
244
245
246
247
248
 
 
249
250
251
252
253
254
255
 
 
 
 
 
 
256
257
258
259
 
 
260
261
262
 
 
263
264
265
266
267
268
269
 
 
270
271
272
273
274
275
276
277
 
 
 
 
278
279
280
 
 
281
282
283
 
 
284
285
286
 
 
287
288
289
 
 
290
291
292
 
 
293
294
295
 
 
296
297
298
299
 
 
300
301
302
303
304
305
306
 
 
307
308
309
 
 
310
311
312
 
 
313
314
315
 
 
316
317
318
 
43
44
45
 
 
 
 
 
 
46
47
48
49
50
51
52
 
 
 
 
53
54
55
56
57
58
59
 
 
 
60
61
62
63
 
 
 
64
65
66
67
68
 
 
69
70
71
 
 
 
72
73
74
75
 
 
76
77
78
 
 
79
80
81
 
 
82
83
84
85
 
 
86
87
88
89
90
91
92
 
 
 
 
93
94
95
96
97
 
 
 
 
 
98
99
100
101
102
103
 
 
104
105
106
 
 
107
108
109
 
 
 
110
111
112
113
 
 
 
114
115
116
117
 
 
 
 
118
119
120
121
122
 
 
 
123
124
125
126
127
128
129
130
 
 
 
 
131
132
133
134
135
 
 
 
136
137
138
139
 
 
 
140
141
142
143
 
 
 
144
145
146
147
 
 
 
 
 
 
148
149
150
151
152
153
154
 
 
 
 
155
156
157
158
159
160
161
162
 
 
163
164
165
 
 
166
167
168
169
170
171
172
173
 
 
 
174
175
176
177
178
179
180
 
 
181
182
183
 
 
184
185
186
 
 
187
188
189
190
191
192
 
 
193
194
195
196
 
 
197
198
199
 
 
200
201
202
203
204
205
206
 
 
 
 
 
 
 
207
208
209
210
211
212
213
214
 
 
 
 
 
 
215
216
217
218
219
220
221
222
223
224
225
226
 
 
227
228
229
 
 
230
231
232
233
234
 
237
238
239
 
 
240
241
242
243
244
245
246
 
 
247
248
249
 
 
 
 
 
 
250
251
252
253
254
255
256
257
 
 
258
259
260
 
 
261
262
263
264
265
266
267
 
 
268
269
270
271
272
273
 
 
 
 
274
275
276
277
278
 
 
279
280
281
 
 
282
283
284
 
 
285
286
287
 
 
288
289
290
 
 
291
292
293
 
 
294
295
296
297
 
 
298
299
300
301
302
303
304
 
 
305
306
307
 
 
308
309
310
 
 
311
312
313
 
 
314
315
316
317
318
@@ -43,192 +43,192 @@
  (_('UI Language'), 'tortoisehg.ui.language', i18n.availablelanguages(),   _('Specify your preferred user interface language (restart needed)')),   (_('Three-way Merge Tool'), 'ui.merge', [], - _('Graphical merge program for resolving merge conflicts. If left' - ' unspecified, Mercurial will use the first applicable tool it finds' - ' on your system or use its internal merge tool that leaves conflict' - ' markers in place. Chose internal:merge to force conflict markers,' - ' internal:prompt to always select local or other, or internal:dump' - ' to leave files in the working directory for manual merging')), + _('Graphical merge program for resolving merge conflicts. If left ' + 'unspecified, Mercurial will use the first applicable tool it finds ' + 'on your system or use its internal merge tool that leaves conflict ' + 'markers in place. Chose internal:merge to force conflict markers, ' + 'internal:prompt to always select local or other, or internal:dump ' + 'to leave files in the working directory for manual merging')),   (_('Visual Diff Tool'), 'tortoisehg.vdiff', [], - _('Specify visual diff tool, as described in the [merge-tools]' - ' section of your Mercurial configuration files. If left' - ' unspecified, TortoiseHg will use the selected merge tool.' - ' Failing that it uses the first applicable tool it finds.')), + _('Specify visual diff tool, as described in the [merge-tools] ' + 'section of your Mercurial configuration files. If left ' + 'unspecified, TortoiseHg will use the selected merge tool. ' + 'Failing that it uses the first applicable tool it finds.')),   (_('Visual Editor'), 'tortoisehg.editor', [],   _('Specify the visual editor used to view files, etc')),   (_('CLI Editor'), 'ui.editor', [], - _('The editor to use during a commit and other instances where' - ' Mercurial needs multiline input from the user. Used by' - ' command line commands, including patch import.')), + _('The editor to use during a commit and other instances where ' + 'Mercurial needs multiline input from the user. Used by ' + 'command line commands, including patch import.')),   (_('Tab Width'), 'tortoisehg.tabwidth', [], - _('Specify the number of spaces that tabs expand to in various' - ' TortoiseHg windows.' - ' Default: Not expanded')), + _('Specify the number of spaces that tabs expand to in various ' + 'TortoiseHg windows. ' + 'Default: Not expanded')),   (_('Max Diff Size'), 'tortoisehg.maxdiff', ['1024', '0'],   _('The maximum size file (in KB) that TortoiseHg will ' - 'show changes for in the changelog, status, and commit windows.' - ' A value of zero implies no limit. Default: 1024 (1MB)')), + 'show changes for in the changelog, status, and commit windows. ' + 'A value of zero implies no limit. Default: 1024 (1MB)')),   (_('Bottom Diffs'), 'gtools.diffbottom', ['False', 'True'], - _('Show the diff panel below the file list in status, shelve, and' - ' commit dialogs.' - ' Default: False (show diffs to right of file list)')), + _('Show the diff panel below the file list in status, shelve, and ' + 'commit dialogs. ' + 'Default: False (show diffs to right of file list)')),   (_('Capture stderr'), 'tortoisehg.stderrcapt', ['True', 'False'], - _('Redirect stderr to a buffer which is parsed at the end of' - ' the process for runtime errors. Default: True')), + _('Redirect stderr to a buffer which is parsed at the end of ' + 'the process for runtime errors. Default: True')),   (_('Fork hgtk'), 'tortoisehg.hgtkfork', ['True', 'False'], - _('When running hgtk from the command line, fork a background' - ' process to run graphical dialogs. Default: True')), + _('When running hgtk from the command line, fork a background ' + 'process to run graphical dialogs. Default: True')),   (_('Full Path Title'), 'tortoisehg.fullpath', ['False', 'True'], - _('Show a full directory path of the repository in the dialog title' - ' instead of just the root directory name. Default: False')), + _('Show a full directory path of the repository in the dialog title ' + 'instead of just the root directory name. Default: False')),   ) + (gtklib.hasspellcheck() and   ((_('Spell Check Language'), 'tortoisehg.spellcheck', [], - _('Default language for spell check. System language is' - ' used if not specified. Examples: en, en_GB, en_US')),) or ())), + _('Default language for spell check. System language is ' + 'used if not specified. Examples: en, en_GB, en_US')),) or ())),    ({'name': 'commit', 'label': _('Commit'), 'icon': 'menucommit.ico'}, (   (_('Username'), 'ui.username', [],   _('Name associated with commits')),   (_('Summary Line Length'), 'tortoisehg.summarylen', ['0', '70'], - _('Maximum length of the commit message summary line.' - ' If set, TortoiseHg will issue a warning if the' - ' summary line is too long or not separated by a' - ' blank line. Default: 0 (unenforced)')), + _('Maximum length of the commit message summary line. ' + 'If set, TortoiseHg will issue a warning if the ' + 'summary line is too long or not separated by a ' + 'blank line. Default: 0 (unenforced)')),   (_('Message Line Length'), 'tortoisehg.messagewrap', ['0', '80'], - _('Word wrap length of the commit message. If' - ' set, the popup menu can be used to format' - ' the message and a warning will be issued' - ' if any lines are too long at commit.' - ' Default: 0 (unenforced)')), + _('Word wrap length of the commit message. If ' + 'set, the popup menu can be used to format ' + 'the message and a warning will be issued ' + 'if any lines are too long at commit. ' + 'Default: 0 (unenforced)')),   (_('Close After Commit'), 'tortoisehg.closeci', ['False', 'True'], - _('Close the commit tool after every successful' - ' commit. Default: False')), + _('Close the commit tool after every successful ' + 'commit. Default: False')),   (_('Push After Commit'), 'tortoisehg.pushafterci', ['False', 'True'], - _('Attempt to push to default push target after every successful' - ' commit. Default: False')), + _('Attempt to push to default push target after every successful ' + 'commit. Default: False')),   (_('Auto Commit List'), 'tortoisehg.autoinc', [], - _('Comma separated list of files that are automatically included' - ' in every commit. Intended for use only as a repository setting.' - ' Default: None (leave blank)')), + _('Comma separated list of files that are automatically included ' + 'in every commit. Intended for use only as a repository setting. ' + 'Default: None (leave blank)')),   (_('Auto Exclude List'), 'tortoisehg.ciexclude', [], - _('Comma separated list of files that are automatically unchecked' - ' when the status, commit, and shelve dialogs are opened.' - ' Default: None (leave blank)')), + _('Comma separated list of files that are automatically unchecked ' + 'when the status, commit, and shelve dialogs are opened. ' + 'Default: None (leave blank)')),   (_('English Messages'), 'tortoisehg.engmsg', ['False', 'True'], - _('Generate English commit messages even if LANGUAGE or LANG' - ' environment variables are set to a non-English language.' - ' This setting is used by the Merge, Tag and Backout dialogs.' - ' Default: False')), + _('Generate English commit messages even if LANGUAGE or LANG ' + 'environment variables are set to a non-English language. ' + 'This setting is used by the Merge, Tag and Backout dialogs. ' + 'Default: False')),   (_('Default Tab'), 'tortoisehg.statustab', ['0', '1', '2'], - _('The tab on which the status and commit tools will open.' - ' 0 - TextDiff, 1 - Hunk Selection, 2 - Commit Preview.' - ' Default: 0')), + _('The tab on which the status and commit tools will open. ' + '0 - TextDiff, 1 - Hunk Selection, 2 - Commit Preview. ' + 'Default: 0')),   )),    ({'name': 'log', 'label': _('Repository Explorer'),   'icon': 'menulog.ico'}, (   (_('Author Coloring'), 'tortoisehg.authorcolor', ['False', 'True'], - _('Color changesets by author name. If not enabled,' - ' the changes are colored green for merge, red for' - ' non-trivial parents, black for normal.' - ' Default: False')), + _('Color changesets by author name. If not enabled, ' + 'the changes are colored green for merge, red for ' + 'non-trivial parents, black for normal. ' + 'Default: False')),   (_('Long Summary'), 'tortoisehg.longsummary', ['False', 'True'], - _('If true, concatenate multiple lines of changeset summary' - ' until they reach 80 characters.' - ' Default: False')), + _('If true, concatenate multiple lines of changeset summary ' + 'until they reach 80 characters. ' + 'Default: False')),   (_('Log Batch Size'), 'tortoisehg.graphlimit', ['500'], - _('The number of revisions to read and display in the' - ' changelog viewer in a single batch.' - ' Default: 500')), + _('The number of revisions to read and display in the ' + 'changelog viewer in a single batch. ' + 'Default: 500')),   (_('Dead Branches'), 'tortoisehg.deadbranch', [], - _('Comma separated list of branch names that should be ignored' - ' when building a list of branch names for a repository.' - ' Default: None (leave blank)')), + _('Comma separated list of branch names that should be ignored ' + 'when building a list of branch names for a repository. ' + 'Default: None (leave blank)')),   (_('Branch Colors'), 'tortoisehg.branchcolors', [], - _('Space separated list of branch names and colors of the form' - ' branch:#XXXXXX. Spaces and colons in the branch name must be' - ' escaped using a backslash (\\). Likewise some other characters' - ' can be escaped in this way, e.g. \\u0040 will be decoded to the' - ' @ character, and \\n to a linefeed.' - ' Default: None (leave blank)')), + _('Space separated list of branch names and colors of the form ' + 'branch:#XXXXXX. Spaces and colons in the branch name must be' + 'escaped using a backslash (\\). Likewise some other characters ' + 'can be escaped in this way, e.g. \\u0040 will be decoded to the ' + '@ character, and \\n to a linefeed. ' + 'Default: None (leave blank)')),   (_('Hide Tags'), 'tortoisehg.hidetags', [], - _('Space separated list of tags that will not be shown.' - ' Useful example: Specify "qbase qparent qtip" to hide the' - ' standard tags inserted by the Mercurial Queues Extension.' - ' Default: None (leave blank)')), + _('Space separated list of tags that will not be shown. ' + 'Useful example: Specify "qbase qparent qtip" to hide the ' + 'standard tags inserted by the Mercurial Queues Extension. ' + 'Default: None (leave blank)')),   (_('Use Expander'), 'tortoisehg.changeset-expander', ['False', 'True'],   _('Show changeset details with an expander')),   (_('Toolbar Style'), 'tortoisehg.logtbarstyle',   ['small', 'large', 'theme'], - _('Adjust the display of the main toolbar in the Repository' - ' Explorer. Values: small, large, or theme. Default: theme')), + _('Adjust the display of the main toolbar in the Repository ' + 'Explorer. Values: small, large, or theme. Default: theme')),  # (_('F/S Encodings'), 'tortoisehg.fsencodings', [], -# _('Comma separated list of encodings used for filenames' -# ' on this computer. Default: none')), +# _('Comma separated list of encodings used for filenames ' +# 'on this computer. Default: none')),   )),    ({'name': 'sync', 'label': _('Synchronize'), 'icon': 'menusynch.ico',   'extra': True}, (   (_('After Pull Operation'), 'tortoisehg.postpull',   ['none', 'update', 'fetch', 'rebase'], - _('Operation which is performed directly after a successful pull.' - ' update equates to pull --update, fetch equates to the fetch' - ' extension, rebase equates to pull --rebase. Default: none')), + _('Operation which is performed directly after a successful pull. ' + 'update equates to pull --update, fetch equates to the fetch ' + 'extension, rebase equates to pull --rebase. Default: none')),   )),    ({'name': 'web', 'label': _('Web Server'), 'icon': 'proxy.ico'}, (   (_('Name'), 'web.name', ['unknown'], - _('Repository name to use in the web interface.' - ' Default is the working directory.')), + _('Repository name to use in the web interface. ' + 'Default is the working directory.')),   (_('Description'), 'web.description', ['unknown'], - _("Textual description of the repository's purpose or" - ' contents.')), + _("Textual description of the repository's purpose or " + 'contents.')),   (_('Contact'), 'web.contact', ['unknown'], - _('Name or email address of the person in charge of the' - ' repository.')), + _('Name or email address of the person in charge of the ' + 'repository.')),   (_('Style'), 'web.style',   ['paper', 'monoblue', 'coal', 'spartan', 'gitweb', 'old'],   _('Which template map style to use')),   (_('Archive Formats'), 'web.allow_archive', ['bz2', 'gz', 'zip'], - _('Comma separated list of archive formats allowed for' - ' downloading')), + _('Comma separated list of archive formats allowed for ' + 'downloading')),   (_('Port'), 'web.port', ['8000'], _('Port to listen on')),   (_('Push Requires SSL'), 'web.push_ssl', ['True', 'False'], - _('Whether to require that inbound pushes be transported' - ' over SSL to prevent password sniffing.')), + _('Whether to require that inbound pushes be transported ' + 'over SSL to prevent password sniffing.')),   (_('Stripes'), 'web.stripes', ['1', '0'], - _('How many lines a "zebra stripe" should span in multiline output.' - ' Default is 1; set to 0 to disable.')), + _('How many lines a "zebra stripe" should span in multiline output. ' + 'Default is 1; set to 0 to disable.')),   (_('Max Files'), 'web.maxfiles', ['10'],   _('Maximum number of files to list per changeset.')),   (_('Max Changes'), 'web.maxchanges', ['10'],   _('Maximum number of changes to list on the changelog.')),   (_('Allow Push'), 'web.allow_push', ['*'], - _('Whether to allow pushing to the repository. If empty or not' - ' set, push is not allowed. If the special value "*", any remote' - ' user can push, including unauthenticated users. Otherwise, the' - ' remote user must have been authenticated, and the authenticated' - ' user name must be present in this list (separated by whitespace' - ' or ","). The contents of the allow_push list are examined after' - ' the deny_push list.')), + _('Whether to allow pushing to the repository. If empty or not ' + 'set, push is not allowed. If the special value "*", any remote ' + 'user can push, including unauthenticated users. Otherwise, the ' + 'remote user must have been authenticated, and the authenticated ' + 'user name must be present in this list (separated by whitespace ' + 'or ","). The contents of the allow_push list are examined after ' + 'the deny_push list.')),   (_('Deny Push'), 'web.deny_push', ['*'], - _('Whether to deny pushing to the repository. If empty or not set,' - ' push is not denied. If the special value "*", all remote users' - ' are denied push. Otherwise, unauthenticated users are all' - ' denied, and any authenticated user name present in this list' - ' (separated by whitespace or ",") is also denied. The contents' - ' of the deny_push list are examined before the allow_push list.')), + _('Whether to deny pushing to the repository. If empty or not set, ' + 'push is not denied. If the special value "*", all remote users ' + 'are denied push. Otherwise, unauthenticated users are all ' + 'denied, and any authenticated user name present in this list ' + '(separated by whitespace or ",") is also denied. The contents ' + 'of the deny_push list are examined before the allow_push list.')),   (_('Encoding'), 'web.encoding', ['UTF-8'],   _('Character encoding name')),   )),    ({'name': 'proxy', 'label': _('Proxy'), 'icon': 'general.ico'}, (   (_('Host'), 'http_proxy.host', [], - _('Host name and (optional) port of proxy server, for' - ' example "myproxy:8000"')), + _('Host name and (optional) port of proxy server, for ' + 'example "myproxy:8000"')),   (_('Bypass List'), 'http_proxy.no', [], - _('Optional. Comma-separated list of host names that' - ' should bypass the proxy')), + _('Optional. Comma-separated list of host names that ' + 'should bypass the proxy')),   (_('User'), 'http_proxy.user', [],   _('Optional. User name to authenticate with at the proxy server')),   (_('Password'), 'http_proxy.passwd', [], @@ -237,82 +237,82 @@
   ({'name': 'email', 'label': _('Email'), 'icon': gtk.STOCK_GOTO_LAST}, (   (_('From'), 'email.from', [], - _('Email address to use in the "From" header and for' - ' the SMTP envelope')), + _('Email address to use in the "From" header and for ' + 'the SMTP envelope')),   (_('To'), 'email.to', [],   _('Comma-separated list of recipient email addresses')),   (_('Cc'), 'email.cc', [],   _('Comma-separated list of carbon copy recipient email addresses')),   (_('Bcc'), 'email.bcc', [], - _('Comma-separated list of blind carbon copy recipient' - ' email addresses')), + _('Comma-separated list of blind carbon copy recipient ' + 'email addresses')),   (_('method'), 'email.method', ['smtp'], - _('Optional. Method to use to send email messages. If value is' - ' "smtp" (default), use SMTP (configured below). Otherwise, use as' - ' name of program to run that acts like sendmail (takes "-f" option' - ' for sender, list of recipients on command line, message on stdin).' - ' Normally, setting this to "sendmail" or "/usr/sbin/sendmail"' - ' is enough to use sendmail to send messages.')), + _('Optional. Method to use to send email messages. If value is ' + '"smtp" (default), use SMTP (configured below). Otherwise, use as ' + 'name of program to run that acts like sendmail (takes "-f" option ' + 'for sender, list of recipients on command line, message on stdin). ' + 'Normally, setting this to "sendmail" or "/usr/sbin/sendmail" ' + 'is enough to use sendmail to send messages.')),   (_('SMTP Host'), 'smtp.host', [], _('Host name of mail server')),   (_('SMTP Port'), 'smtp.port', ['25'], - _('Port to connect to on mail server.' - ' Default: 25')), + _('Port to connect to on mail server. ' + 'Default: 25')),   (_('SMTP TLS'), 'smtp.tls', ['False', 'True'], - _('Connect to mail server using TLS.' - ' Default: False')), + _('Connect to mail server using TLS. ' + 'Default: False')),   (_('SMTP Username'), 'smtp.username', [],   _('Username to authenticate to mail server with')),   (_('SMTP Password'), 'smtp.password', [],   _('Password to authenticate to mail server with')),   (_('Local Hostname'), 'smtp.local_hostname', [], - _('Hostname the sender can use to identify itself to the' - ' mail server.')), + _('Hostname the sender can use to identify itself to the ' + 'mail server.')),   )),    ({'name': 'diff', 'label': _('Diff'), 'icon': gtk.STOCK_JUSTIFY_FILL}, (   (_('Patch EOL'), 'patch.eol', ['auto', 'strict', 'crlf', 'lf'], - _('Normalize file line endings during and after patch to lf or' - ' crlf. Strict does no normalization. Auto does per-file' - ' detection, and is the recommended setting.' - ' Default: strict')), + _('Normalize file line endings during and after patch to lf or ' + 'crlf. Strict does no normalization. Auto does per-file ' + 'detection, and is the recommended setting. ' + 'Default: strict')),   (_('Git Format'), 'diff.git', ['False', 'True'], - _('Use git extended diff header format.' - ' Default: False')), + _('Use git extended diff header format. ' + 'Default: False')),   (_('No Dates'), 'diff.nodates', ['False', 'True'], - _('Do not include modification dates in diff headers.' - ' Default: False')), + _('Do not include modification dates in diff headers. ' + 'Default: False')),   (_('Show Function'), 'diff.showfunc', ['False', 'True'], - _('Show which function each change is in.' - ' Default: False')), + _('Show which function each change is in. ' + 'Default: False')),   (_('Ignore White Space'), 'diff.ignorews', ['False', 'True'], - _('Ignore white space when comparing lines.' - ' Default: False')), + _('Ignore white space when comparing lines. ' + 'Default: False')),   (_('Ignore WS Amount'), 'diff.ignorewsamount', ['False', 'True'], - _('Ignore changes in the amount of white space.' - ' Default: False')), + _('Ignore changes in the amount of white space. ' + 'Default: False')),   (_('Ignore Blank Lines'), 'diff.ignoreblanklines', ['False', 'True'], - _('Ignore changes whose lines are all blank.' - ' Default: False')), + _('Ignore changes whose lines are all blank. ' + 'Default: False')),   (_('Coloring Style'), 'tortoisehg.diffcolorstyle',   ['none', 'foreground', 'background'], - _('Adjust the coloring style of diff lines in the changeset' - ' viewer. Default: foreground')), + _('Adjust the coloring style of diff lines in the changeset ' + 'viewer. Default: foreground')),   )),    ({'name': 'font', 'label': _('Font'), 'icon': gtk.STOCK_SELECT_FONT,   'extra': True, 'width': 16}, (   (_('Commit Message'), 'gtools.fontcomment', [], - _('Font used in changeset viewer and commit log text.' - ' Default: monospace 10')), + _('Font used in changeset viewer and commit log text. ' + 'Default: monospace 10')),   (_('Diff Text'), 'gtools.fontdiff', [], - _('Font used for diffs in status and commit tools.' - ' Default: monospace 10')), + _('Font used for diffs in status and commit tools. ' + 'Default: monospace 10')),   (_('File List'), 'gtools.fontlist', [], - _('Font used in file lists in status and commit tools.' - ' Default: sans 9')), + _('Font used in file lists in status and commit tools. ' + 'Default: sans 9')),   (_('Command Output'), 'gtools.fontlog', [], - _('Font used in command output window.' - ' Default: monospace 10')), + _('Font used in command output window. ' + 'Default: monospace 10')),   )),    ({'name': 'extensions', 'label': _('Extensions'), 'icon': gtk.STOCK_EXECUTE,
 
158
159
160
161
 
162
163
164
 
158
159
160
 
161
162
163
164
@@ -158,7 +158,7 @@
  dialog = gtklib.MessageDialog(flags=gtk.DIALOG_MODAL)   dialog.set_title(_('Shelve'))   dialog.set_markup(_('<b>Shelve file exists!</b>')) - dialog.add_buttons(_('Overwrite'), 1, + dialog.add_buttons(_('Replace'), 1,   _('Append'), 2,   _('Cancel'), -1)   dialog.set_transient_for(self)
 
86
87
88
89
90
 
 
91
92
93
 
109
110
111
112
113
 
 
114
115
116
 
212
213
214
215
216
 
 
217
218
219
 
86
87
88
 
 
89
90
91
92
93
 
109
110
111
 
 
112
113
114
115
116
 
212
213
214
 
 
215
216
217
218
219
@@ -86,8 +86,8 @@
  self.expander.connect('notify::expanded', self.options_expanded)     ### force option (fixed) - self.forceopt = gtk.CheckButton(_('Discard local changes, no backup' - ' (-f/--force)')) + self.forceopt = gtk.CheckButton(_('Discard local changes, no backup ' + '(-f/--force)'))   table.add_row(self.expander, self.forceopt)     # signal handlers @@ -109,8 +109,8 @@
  self.butable.add_row(None, radio, ypad=0)   return radio   self.buopt_all = add_type(_('Backup all (default)')) - self.buopt_part = add_type(_('Backup unrelated changesets' - ' (-b/--backup)')) + self.buopt_part = add_type(_('Backup unrelated changesets ' + '(-b/--backup)'))   self.buopt_none = add_type(_('No backup (-n/--nobackup)'))     # layout group @@ -212,8 +212,8 @@
  else:   if not isclean():   ret = gdialog.CustomPrompt(_('Confirm Strip'), - _('Detected uncommitted local changes.\nDo' - ' you want to discard them and continue?'), + _('Detected uncommitted local changes.\nDo ' + 'you want to discard them and continue?'),   self, (_('&Yes (--force)'), _('&No')),   default=1, esc=1).run()   if ret == 0:
 
367
368
369
370
371
 
 
372
373
374
 
367
368
369
 
 
370
371
372
373
374
@@ -367,8 +367,8 @@
  self.copies = cpy   self.ui = repo.ui   - lbl = gtk.Label(_('Temporary files are removed when this dialog' - ' is closed')) + lbl = gtk.Label(_('Temporary files are removed when this dialog ' + 'is closed'))   self.vbox.pack_start(lbl, False, False, 2)     scroller = gtk.ScrolledWindow()
 
176
177
178
179
 
180
181
182
 
176
177
178
 
179
180
181
182
@@ -176,7 +176,7 @@
  return type, rawpath.split('/', 1)[-1]     files = {} - pf = open(self._path) + pf = open(self._path, 'rb')   try:   try:   # consume comments and headers
 
180
181
182
183
184
185
186
187
188
189
190
191
 
 
192
193
194
 
180
181
182
 
 
 
 
183
184
185
 
 
186
187
188
189
190
@@ -180,15 +180,11 @@
    if not self.rej:   return - if self.hunks != 1: - hunkstr = "s" - else: - hunkstr = ""     fname = self.fname + ".rej"   self.ui.warn( - _("%d out of %d hunk%s FAILED -- saving rejects to file %s\n") % - (len(self.rej), self.hunks, hunkstr, fname)) + _("%d out of %d hunks FAILED -- saving rejects to file %s\n") % + (len(self.rej), self.hunks, fname))   try: os.unlink(fname)   except:   pass