Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.9, 1.9.1, and 1.9.2

hgqt: route log and progress reports through repowidget

Fixes a number of layering violations. The cmdui.Runner and Widget will now
emit progress and output signals that parent widgets may optionally connect to.
Use of the internal cmdui.Core.output_text text buffer can be disabled
entirely.

Use the new ProgressMonitor and ThgStatusBar everywhere. Move the workbench
status bar from the output log dock widget to the main workbench window, to
both give it more room and to make them visible when the log dock is closed.

Changeset 29d847314160

Parent 6f444bff6676

by Steve Borho

Changes to 7 files · Browse files at 29d847314160 Showing diff from parent 6f444bff6676 Diff from another changeset...

 
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
 
73
74
75
76
77
78
 
 
 
 
79
80
81
82
83
84
 
85
86
87
 
 
 
 
88
89
90
 
103
104
105
106
107
 
 
108
109
110
 
126
127
128
129
130
131
132
133
134
 
 
 
 
 
 
135
136
137
138
139
 
 
 
 
 
140
141
142
 
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
 
193
194
195
196
197
198
 
 
 
199
200
201
 
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
 
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
 
283
284
285
286
287
288
 
 
 
289
290
291
 
 
 
 
292
293
294
 
306
307
308
309
 
310
311
312
313
314
315
316
317
 
 
 
 
 
 
318
319
320
321
322
323
324
325
326
 
 
 
 
327
328
329
 
337
338
339
340
 
341
342
 
343
344
345
 
406
407
408
409
 
 
 
 
 
410
411
 
412
413
414
415
 
416
417
418
419
420
 
 
 
 
 
421
422
423
 
428
429
430
431
432
 
 
433
434
435
 
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
 
118
119
120
 
121
 
122
123
124
125
126
127
128
 
 
 
129
130
 
131
132
133
134
135
136
137
138
 
151
152
153
 
 
154
155
156
157
158
 
174
175
176
 
 
 
 
 
 
177
178
179
180
181
182
183
 
 
 
 
184
185
186
187
188
189
190
191
 
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
 
236
237
238
 
 
 
239
240
241
242
243
244
 
249
250
251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
253
254
 
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
 
300
301
302
 
 
 
303
304
305
306
307
 
308
309
310
311
312
313
314
 
326
327
328
 
329
330
331
332
333
 
 
 
 
334
335
336
337
338
339
340
341
 
 
 
 
 
 
 
342
343
344
345
346
347
348
 
356
357
358
 
359
360
 
361
362
363
364
 
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
 
456
457
458
 
 
459
460
461
462
463
@@ -15,55 +15,100 @@
 local = localgettext()    class ProgressMonitor(QWidget): + 'Progress bar for use in workbench status bar' + def __init__(self, topic, parent): + super(ProgressMonitor, self).__init__(parent=parent)   - def __init__(self): - super(ProgressMonitor, self).__init__() - - # main layout box - vbox = QVBoxLayout() - vbox.setContentsMargins(*(0,)*4) - self.setLayout(vbox) - - ## status layout box   hbox = QHBoxLayout()   hbox.setContentsMargins(*(0,)*4) - vbox.addLayout(hbox) + self.setLayout(hbox) + self.idle = False   - self.status_label = QLabel() - hbox.addWidget(self.status_label, 1) - - self.prog_label = QLabel() - hbox.addWidget(self.prog_label, 0, Qt.AlignRight) - - ## progressbar   self.pbar = QProgressBar()   self.pbar.setTextVisible(False)   self.pbar.setMinimum(0) - vbox.addWidget(self.pbar) + hbox.addWidget(self.pbar)   - # prepare to show - self.clear_progress() + self.topic = QLabel(topic) + hbox.addWidget(self.topic, 0)   - ### Public Methods ### + self.status = QLabel() + hbox.addWidget(self.status, 1)   - def clear_progress(self):   self.pbar.setMaximum(100)   self.pbar.reset() - self.status_label.setText('') - self.prog_label.setText('') - self.inprogress = False + self.status.setText('')   - def fillup_progress(self): - """stick progress to full""" - self.clear_progress() - self.pbar.setValue(self.pbar.maximum()) + def clear(self): + self.pbar.setMinimum(0) + self.pbar.setMaximum(100) + self.pbar.setValue(100) + self.status.setText('') + self.idle = True   - def unknown_progress(self): + def setcounts(self, cur, max): + self.pbar.setMaximum(max) + self.pbar.setValue(cur) + + def unknown(self):   self.pbar.setMinimum(0)   self.pbar.setMaximum(0)   - def set_text(self, text): - self.status_label.setText(text) + +class ThgStatusBar(QStatusBar): + def __init__(self, parent=None): + QStatusBar.__init__(self, parent=parent) + self.topics = {} + self.lbl = QLabel() + self.addWidget(self.lbl) + + def showMessage(self, str): + self.lbl.setText(str) + + def clear(self): + for key in self.topics: + pm = self.topics[key] + self.removeWidget(pm) + del self.topics[key] + + @pyqtSlot(thread.DataWrapper) + def progress(self, wrapper, root=None): + 'Progress signal received from repowidget' + topic, item, pos, total, unit = wrapper.data + # topic is current operation + # pos is the current numeric position (revision, bytes) + # item is a non-numeric marker of current position (current file) + # unit is a string label + # total is the highest expected pos + # All topics should be marked closed by setting pos to None + if root: + key = (root, topic) + else: + key = topic + if pos is None or (not pos and not total): + if key in self.topics: + pm = self.topics[key] + self.removeWidget(pm) + del self.topics[key] + return + if key not in self.topics: + pm = ProgressMonitor(topic, self) + self.addWidget(pm) + self.topics[key] = pm + else: + pm = self.topics[key] + if total: + fmt = '%s / %s ' % (str(pos), str(total)) + if unit: + fmt += unit + pm.status.setText(fmt) + pm.setcounts(pos, total) + else: + if item: + item = hglib.tounicode(item)[-30:] + pm.status.setText('%s %s' % (str(pos), item)) + pm.unknown() +    class Core(QObject):   """Core functionality for running Mercurial command. @@ -73,18 +118,21 @@
  commandStarted = pyqtSignal()   commandFinished = pyqtSignal(thread.DataWrapper)   commandCanceling = pyqtSignal() - clearSignal = pyqtSignal()   - def __init__(self, logwidget=None): + output = pyqtSignal(thread.DataWrapper) + progress = pyqtSignal(thread.DataWrapper) + + def __init__(self, useInternal):   super(Core, self).__init__()     self.thread = None - self.output_text = QTextBrowser() - self.output_text.document().setDefaultStyleSheet(qtlib.thgstylesheet) - self.pmon = None + self.stbar = None   self.queue = [] - self.log = logwidget   self.display = None + self.internallog = useInternal + if useInternal: + self.output_text = QTextBrowser() + self.output_text.document().setDefaultStyleSheet(qtlib.thgstylesheet)     ### Public Methods ###   @@ -103,8 +151,8 @@
  self.thread.abort()   self.commandCanceling.emit()   - def set_pmon(self, pmon): - self.pmon = pmon + def set_stbar(self, stbar): + self.stbar = stbar     def is_running(self):   return bool(self.thread and self.thread.isRunning()) @@ -126,17 +174,18 @@
    self.thread.started.connect(self.command_started)   self.thread.commandFinished.connect(self.command_finished) - if self.log: - self.thread.outputReceived.connect(self.log.output) - self.thread.errorReceived.connect(self.log.output) - self.thread.progressReceived.connect(self.log.progress) - self.clearSignal.connect(self.log.clear) - else: + + self.thread.outputReceived.connect(self.output) + self.thread.errorReceived.connect(self.output) + self.thread.progressReceived.connect(self.progress) + + if self.internallog:   self.thread.outputReceived.connect(self.output_received) - self.thread.errorReceived.connect(self.output_received) - self.clearSignal.connect(self.output_text.clear) - if self.pmon: - self.thread.progressReceived.connect(self.progress_received) + self.thread.errorReceived.connect(self.output) + + if self.stbar: + self.thread.progressReceived.connect(self.stbar.progress) +   if self.display:   cmd = '%% hg %s\n' % self.display   else: @@ -156,36 +205,30 @@
  self.output_text.verticalScrollBar().setSliderPosition(max)     def clear_output(self): - self.clearSignal.emit() + if self.internallog: + self.output_text.clear()     ### Signal Handlers ###     def command_started(self): - if self.pmon: - self.pmon.set_text(_('Running...')) - self.pmon.unknown_progress() + if self.stbar: + self.stbar.showMessage(_('Running...'))     self.commandStarted.emit()     def command_finished(self, wrapper):   ret = wrapper.data   - if self.pmon: + if self.stbar:   if ret is None: - self.pmon.clear_progress() - if self.pmon.pbar.maximum() == 0: # busy indicator - if ret == 0: # finished successfully - self.pmon.fillup_progress() - else: - self.pmon.clear_progress() - if ret is None: + self.stbar.clear()   if self.thread.abortbyuser:   status = _('Terminated by user')   else:   status = _('Terminated')   else:   status = _('Finished') - self.pmon.set_text(status) + self.stbar.showMessage(status)     if ret == 0 and self.run_next():   return # run next command @@ -193,9 +236,9 @@
  self.commandFinished.emit(wrapper)     def command_canceling(self): - if self.pmon: - self.pmon.set_text(_('Canceling...')) - self.pmon.unknown_progress() + if self.stbar: + self.stbar.showMessage(_('Canceling...')) + self.stbar.clear()     self.commandCanceling.emit()   @@ -206,36 +249,6 @@
  style = qtlib.geteffect(label)   self.append_output(msg, style)   - def progress_received(self, wrapper): - if self.thread.isFinished(): - self.pmon.clear_progress() - return - - counting = False - topic, item, pos, total, unit = wrapper.data - if pos is None: - self.pmon.clear_progress() - return - if total is None: - count = '%d' % pos - counting = True - else: - self.pmon.pbar.setMaximum(total) - self.pmon.pbar.setValue(pos) - count = '%d / %d' % (pos, total) - if unit: - count += ' ' + unit - self.pmon.prog_label.setText(hglib.tounicode(count)) - if item: - status = '%s: %s' % (topic, item) - else: - status = local._('Status: %s') % topic - self.pmon.status_label.setText(hglib.tounicode(status)) - self.pmon.inprogress = True - - if not self.pmon.inprogress or counting: - # use indeterminate mode - self.pmon.pbar.setMinimum(0)    class Widget(QWidget):   """An embeddable widget for running Mercurial command""" @@ -244,35 +257,39 @@
  commandFinished = pyqtSignal(thread.DataWrapper)   commandCanceling = pyqtSignal()   - def __init__(self, logwidget=None): + output = pyqtSignal(thread.DataWrapper) + progress = pyqtSignal(thread.DataWrapper) + makeLogVisible = pyqtSignal(bool) + + def __init__(self, useInternal=True, parent=None):   super(Widget, self).__init__()   - self.core = Core(logwidget) + self.internallog = useInternal + self.core = Core(useInternal)   self.core.commandStarted.connect(self.commandStarted)   self.core.commandFinished.connect(self.commandFinished)   self.core.commandCanceling.connect(self.commandCanceling) - if logwidget: + self.core.output.connect(self.output) + self.core.progress.connect(self.progress) + if not useInternal:   return   - # main layout grid - grid = QGridLayout() - grid.setSpacing(4) - grid.setContentsMargins(*(1,)*4) + vbox = QVBoxLayout() + vbox.setSpacing(4) + vbox.setContentsMargins(*(1,)*4) + + # command output area + self.core.output_text.setHidden(True) + vbox.addWidget(self.core.output_text, 1)     ## status and progress labels - self.pmon = ProgressMonitor() - self.core.set_pmon(self.pmon) - grid.addWidget(self.pmon, 0, 0) - - # command output area - grid.addWidget(self.core.output_text, 1, 0, 5, 0) - grid.setRowStretch(1, 1) + self.stbar = ThgStatusBar() + #self.stbar.setSizeGripEnabled(False) + self.core.set_stbar(self.stbar) + vbox.addWidget(self.stbar)     # widget setting - self.setLayout(grid) - - # prepare to show - self.core.output_text.setHidden(True) + self.setLayout(vbox)     ### Public Methods ###   @@ -283,12 +300,15 @@
  self.core.cancel()     def show_output(self, visible): - if self.core.log: - return - self.core.output_text.setShown(visible) + self.makeLogVisible.emit(True) + if self.internallog: + self.core.output_text.setShown(visible)     def is_show_output(self): - return self.core.output_text.isVisible() + if self.internallog: + return self.core.output_text.isVisible() + else: + return False     def get_rawoutput(self):   return self.core.get_rawoutput() @@ -306,24 +326,23 @@
    self.finishfunc = finishfunc   - self.core = Core() + self.core = Core(True)   self.core.commandStarted.connect(self.commandStarted)   self.core.commandFinished.connect(self.command_finished)   self.core.commandCanceling.connect(self.commandCanceling)   - # main layout grid - grid = QGridLayout() - grid.setSpacing(6) - grid.setContentsMargins(*(7,)*4) + vbox = QVBoxLayout() + vbox.setSpacing(4) + vbox.setContentsMargins(*(1,)*4) + + # command output area + vbox.addWidget(self.core.output_text, 1)     ## status and progress labels - self.pmon = ProgressMonitor() - self.core.set_pmon(self.pmon) - grid.addWidget(self.pmon, 0, 0) - - # command output area - grid.addWidget(self.core.output_text, 1, 0, 5, 0) - grid.setRowStretch(1, 1) + self.stbar = ThgStatusBar() + #self.stbar.setSizeGripEnabled(False) + self.core.set_stbar(self.stbar) + vbox.addWidget(self.stbar)     # bottom buttons   buttons = QDialogButtonBox() @@ -337,9 +356,9 @@
  self.detail_btn.setCheckable(True)   self.detail_btn.setChecked(True)   self.detail_btn.toggled.connect(self.show_output) - grid.addWidget(buttons, 7, 0) + vbox.addWidget(buttons)   - self.setLayout(grid) + self.setLayout(vbox)   self.setWindowTitle(_('TortoiseHg Command Dialog'))   self.resize(540, 420)   @@ -406,18 +425,27 @@
  commandFinished = pyqtSignal(thread.DataWrapper)   commandCanceling = pyqtSignal()   - def __init__(self, title=_('TortoiseHg'), parent=None, log=None): + output = pyqtSignal(thread.DataWrapper) + progress = pyqtSignal(thread.DataWrapper) + makeLogVisible = pyqtSignal(bool) + + def __init__(self, title=_('TortoiseHg'), useInternal=True, parent=None):   super(Runner, self).__init__()   + self.internallog = useInternal   self.title = title   self.parent = parent   - self.core = Core(log) + self.core = Core(useInternal)   self.core.commandStarted.connect(self.commandStarted)   self.core.commandFinished.connect(self.command_finished)   self.core.commandCanceling.connect(self.commandCanceling)   - self.core.output_text.setMinimumSize(460, 320) + self.core.output.connect(self.output) + self.core.progress.connect(self.progress) + + if useInternal: + self.core.output_text.setMinimumSize(460, 320)     ### Public Methods ###   @@ -428,8 +456,8 @@
  self.core.cancel()     def show_output(self, visible=True): - if self.core.log: - self.core.log.setShown(visible) + self.makeLogVisible.emit(True) + if not self.internallog:   return   if not hasattr(self, 'dlg'):   self.dlg = QDialog(self.parent)
 
16
17
18
19
 
20
21
22
 
34
35
36
37
38
 
 
 
 
 
 
39
40
41
 
46
47
48
49
 
 
 
 
50
51
52
 
864
865
866
867
868
869
870
 
871
872
873
 
876
877
878
879
 
880
881
 
 
 
 
 
882
883
884
 
895
896
897
898
899
900
901
 
917
918
919
920
921
922
923
924
925
 
16
17
18
 
19
20
21
22
 
34
35
36
 
 
37
38
39
40
41
42
43
44
45
 
50
51
52
 
53
54
55
56
57
58
59
 
871
872
873
 
874
875
876
877
878
879
880
 
883
884
885
 
886
887
888
889
890
891
892
893
894
895
896
 
907
908
909
 
910
911
912
 
928
929
930
 
 
 
931
932
933
@@ -16,7 +16,7 @@
 from tortoisehg.hgqt.i18n import _  from tortoisehg.util import hglib, shlib, paths, wconfig   -from tortoisehg.hgqt import qtlib, status, cmdui, branchop, revpanelwidget +from tortoisehg.hgqt import qtlib, status, cmdui, branchop, revpanelwidget, thread  from tortoisehg.hgqt.sync import loadIniFile    # Technical Debt for CommitWidget @@ -34,8 +34,12 @@
  showMessage = pyqtSignal(str)   commitComplete = pyqtSignal()   - def __init__(self, pats, opts, root=None, parent=None, logwidget=None): - QWidget.__init__(self, parent) + progress = pyqtSignal(thread.DataWrapper) + output = pyqtSignal(thread.DataWrapper) + makeLogVisible = pyqtSignal(bool) + + def __init__(self, pats, opts, root=None, embedded=False, parent=None): + QWidget.__init__(self, parent=parent)     self.opts = opts # user, date   self.stwidget = status.StatusWidget(pats, opts, root, self) @@ -46,7 +50,10 @@
  self.qref = False     self.repo = repo = self.stwidget.repo - self.runner = cmdui.Runner(_('Commit'), self, logwidget) + self.runner = cmdui.Runner(_('Commit'), not embedded, self) + self.runner.output.connect(self.output) + self.runner.progress.connect(self.progress) + self.runner.makeLogVisible.connect(self.makeLogVisible)   self.runner.commandFinished.connect(self.commandFinished)     repo.configChanged.connect(self.configChanged) @@ -864,10 +871,10 @@
   # Technical Debt for standalone tool  # add a toolbar for refresh -# add a statusbar and simple progressbar    class CommitDialog(QDialog):   'Standalone commit tool, a wrapper for CommitWidget' +   def __init__(self, pats, opts, parent=None):   QDialog.__init__(self, parent)   self.pats = pats @@ -876,9 +883,14 @@
  layout = QVBoxLayout()   self.setLayout(layout)   - commit = CommitWidget(pats, opts, None, self) + commit = CommitWidget(pats, opts, None, False, self)   layout.addWidget(commit, 1)   + self.statusbar = cmdui.ThgStatusBar(self) + layout.addWidget(self.statusbar) + commit.showMessage.connect(self.statusbar.showMessage) + commit.progress.connect(self.statusbar.progress) +   BB = QDialogButtonBox   bb = QDialogButtonBox(BB.Ok|BB.Cancel|BB.Discard)   bb.accepted.connect(self.accept) @@ -895,7 +907,6 @@
  commit.restoreState(s.value('commit/state').toByteArray())   self.restoreGeometry(s.value('commit/geom').toByteArray())   commit.loadConfigs(s) - commit.showMessage.connect(self.showMessage)   commit.loadComplete.connect(self.updateUndo)   commit.commitComplete.connect(self.postcommit)   commit.commitButtonName.connect(self.setButtonName) @@ -917,9 +928,6 @@
  self.bb.button(BB.Discard).setEnabled(False)   self.bb.button(BB.Discard).setToolTip('')   - def showMessage(self, msg): - print msg -   def keyPressEvent(self, event):   if event.key() == Qt.Key_Escape:   self.reject()
 
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
 
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
 
41
42
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
45
46
 
49
50
51
52
53
54
55
56
57
58
59
60
61
 
 
 
 
62
63
64
65
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -41,43 +41,6 @@
  self.logte.setWordWrapMode(QTextOption.NoWrap)   vbox.addWidget(self.logte, 1)   - self.topics = {} - self.stbar = QStatusBar() - vbox.addWidget(self.stbar) - - @pyqtSlot(thread.DataWrapper) - def progress(self, wrapper): - # topic is current operation - # pos is the current numeric position (revision, bytes) - # item is a non-numeric marker of current position (current file) - # unit is a string label - # total is the highest expected pos - # All topics should be marked closed by setting pos to None - topic, item, pos, total, unit = wrapper.data - if pos is None or (not pos and not total): - if topic in self.topics: - pm = self.topics[topic] - self.stbar.removeWidget(pm) - del self.topics[topic] - return - if topic not in self.topics: - pm = ProgressMonitor(topic) - self.stbar.addWidget(pm) - self.topics[topic] = pm - else: - pm = self.topics[topic] - if total: - fmt = '%s / %s ' % (str(pos), str(total)) - if unit: - fmt += unit - pm.status.setText(fmt) - pm.setcounts(pos, total) - else: - if item: - item = hglib.tounicode(item)[-30:] - pm.status.setText('%s %s' % (str(pos), item)) - pm.unknown() -   @pyqtSlot(thread.DataWrapper)   def output(self, wrapper):   msg, label = wrapper.data @@ -86,63 +49,18 @@
  style = qtlib.geteffect(label)   self.logMessage(msg, style)   + @pyqtSlot() + def clear(self): + self.logte.clear() +   def logMessage(self, msg, style=''):   if msg.endsWith('\n'):   msg.chop(1)   msg = msg.replace('\n', '<br/>')   self.logte.appendHtml('<font style="%s">%s</font>' % (style, msg))   - @pyqtSlot() - def clear(self): - self.logte.clear() -   def showEvent(self, event):   self.visibilityChanged.emit(True)     def hideEvent(self, event):   self.visibilityChanged.emit(False) - - -class ProgressMonitor(QWidget): - def __init__(self, topic): - super(ProgressMonitor, self).__init__() - - hbox = QHBoxLayout() - hbox.setContentsMargins(*(0,)*4) - self.setLayout(hbox) - self.idle = False - - self.pbar = QProgressBar() - self.pbar.setTextVisible(False) - self.pbar.setMinimum(0) - hbox.addWidget(self.pbar) - - self.topic = QLabel(topic) - hbox.addWidget(self.topic, 0) - - self.status = QLabel() - hbox.addWidget(self.status, 1) - - self.pbar.setMaximum(100) - self.pbar.reset() - self.status.setText('') - - def reuse(self, topic): - self.topic.setText(topic) - self.status.setText('') - self.idle = False - - def clear(self): - self.pbar.setMinimum(0) - self.pbar.setMaximum(100) - self.pbar.setValue(100) - self.status.setText('') - self.idle = True - - def setcounts(self, cur, max): - self.pbar.setMaximum(max) - self.pbar.setValue(cur) - - def unknown(self): - self.pbar.setMinimum(0) - self.pbar.setMaximum(0)
 
402
403
404
405
 
406
407
408
 
420
421
422
423
 
424
425
426
 
439
440
441
442
 
443
444
445
 
402
403
404
 
405
406
407
408
 
420
421
422
 
423
424
425
426
 
439
440
441
 
442
443
444
445
@@ -402,7 +402,7 @@
  self.wd_text.setText(text % dict(name=patch))   self.wd_text.setShown(True)   self.check_status(callback) - self.runner = cmdui.Runner(_('MQ - TortoiseHg'), self) + self.runner = cmdui.Runner(_('MQ - TortoiseHg'), True, self)   self.runner.commandFinished.connect(finished)   self.wizard().repo.incrementBusyCount()   self.runner.run(['qnew', patch], @@ -420,7 +420,7 @@
  if wrapper.data == 0:   self.check_status()   cmdline = ['update', '--clean', '--rev', self.wizard().local] - self.runner = cmdui.Runner(_('Discard - TortoiseHg'), self) + self.runner = cmdui.Runner(_('Discard - TortoiseHg'), True, self)   self.runner.commandFinished.connect(finished)   self.wizard().repo.incrementBusyCount()   self.runner.run(cmdline) @@ -439,7 +439,7 @@
  '%(new)s</b>. <a href="rename:%(new)s"><b>'   'Rename</b></a> again?')   self.wd_text.setText(text % dict(old=patch, new=name)) - self.runner = cmdui.Runner(_('Rename - TortoiseHg'), self) + self.runner = cmdui.Runner(_('Rename - TortoiseHg'), True, self)   self.runner.commandFinished.connect(finished)   self.wizard().repo.incrementBusyCount()   self.runner.run(['qrename', oldpatch, newpatch])
 
21
22
23
 
24
25
26
 
44
45
46
 
47
48
49
 
53
54
55
 
56
57
 
 
 
 
 
 
 
 
 
 
 
58
59
60
 
130
131
132
133
134
 
 
 
 
 
 
 
 
135
136
137
 
157
158
159
160
 
 
 
 
 
 
161
162
163
 
629
630
631
632
633
634
635
636
 
 
 
 
637
 
638
639
 
21
22
23
24
25
26
27
 
45
46
47
48
49
50
51
 
55
56
57
58
59
 
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 
143
144
145
 
 
146
147
148
149
150
151
152
153
154
155
156
 
176
177
178
 
179
180
181
182
183
184
185
186
187
 
653
654
655
 
 
656
657
658
659
660
661
662
663
664
665
 
@@ -21,6 +21,7 @@
 from tortoisehg.hgqt import cmdui, update, tag, backout, merge, visdiff  from tortoisehg.hgqt import archive, thgimport, thgstrip, run, thgrepo   +from tortoisehg.hgqt.thread import DataWrapper  from tortoisehg.hgqt.repoview import HgRepoView  from tortoisehg.hgqt.revdetailswidget import RevDetailsWidget  from tortoisehg.hgqt.commit import CommitWidget @@ -44,6 +45,7 @@
  repo.repositoryDestroyed.connect(self.repositoryDestroyed)   repo.configChanged.connect(self.configChanged)   self.workbench = workbench +   self._reload_rev = '.' # select working parent at startup   self.currentMessage = ''   self.runner = None @@ -53,8 +55,19 @@
  self.setupUi()   self.createActions()   self.setupModels() + self.restoreSettings()   - self.restoreSettings() + @pyqtSlot(DataWrapper) + def progress(self, w): + self.workbench.statusbar.progress(w, self.repo.root) + + @pyqtSlot(DataWrapper) + def output(self, w): + self.workbench.log.output(w) + + @pyqtSlot(bool) + def makeLogVisible(self, v): + self.workbench.log.setShown(v)     def setupUi(self):   SP = QSizePolicy @@ -130,8 +143,14 @@
  pats = {}   opts = {}   b = QPushButton('Commit') - cw = CommitWidget(pats, opts, self.repo.root, self, - self.workbench.log) + cw = CommitWidget(pats, opts, self.repo.root, True, self) + + # Shared widgets must be connected directly to workbench + cw.output.connect(self.workbench.log.output) + cw.progress.connect(lambda w: + self.workbench.statusbar.progress(w, self.repo.root)) + cw.makeLogVisible.connect(self.workbench.statusbar.setShown) +   cw.showMessage.connect(self.showMessage)   cw.buttonHBox.addWidget(b)   cw.commitButtonName.connect(lambda n: b.setText(n)) @@ -157,7 +176,12 @@
  def createSyncWidget(self):   sw = getattr(self.repo, '_syncwidget', None) # TODO: ugly   if not sw: - sw = SyncWidget(root=self.repo.root, log=self.workbench.log) + sw = SyncWidget(self.repo.root, True, self) + # Shared widgets must be connected directly to workbench + sw.output.connect(self.workbench.log.output) + sw.progress.connect(lambda w: + self.workbench.statusbar.progress(w, self.repo.root)) + sw.makeLogVisible.connect(self.workbench.statusbar.setShown)   self.repo._syncwidget = sw   sw.outgoingNodes.connect(self.setOutgoingNodes)   sw.showMessage.connect(self.showMessage) @@ -629,11 +653,13 @@
  InfoMsgBox(_('Unable to start'),   _('Previous command is still running'))   return - self.runner = cmdui.Runner(title, self, self.workbench.log) - self.repo.incrementBusyCount()   def finished(ret):   self.repo.decrementBusyCount()   self.runner = None + self.runner = cmdui.Runner(title, False, self) + self.runner.output.connect(self.output) + self.runner.progress.connect(self.progress) + self.runner.makeLogVisible.connect(self.makeLogVisible)   self.runner.commandFinished.connect(finished) + self.repo.incrementBusyCount()   self.runner.run(cmdline) -
 
28
29
30
31
 
 
 
 
 
32
33
34
 
44
45
46
47
48
 
49
50
51
 
122
123
124
125
 
126
127
128
 
 
 
 
 
129
130
 
131
 
132
133
134
 
138
139
140
141
142
 
 
 
143
144
145
 
271
272
273
274
275
 
 
276
277
278
 
326
327
328
329
 
330
331
332
 
28
29
30
 
31
32
33
34
35
36
37
38
 
48
49
50
 
 
51
52
53
54
 
125
126
127
 
128
129
130
131
132
133
134
135
136
137
 
138
139
140
141
142
143
 
147
148
149
 
 
150
151
152
153
154
155
 
281
282
283
 
 
284
285
286
287
288
 
336
337
338
 
339
340
341
342
@@ -28,7 +28,11 @@
  outgoingNodes = pyqtSignal(object)   showMessage = pyqtSignal(str)   - def __init__(self, root, parent=None, log=None, **opts): + output = pyqtSignal(object) + progress = pyqtSignal(object) + makeLogVisible = pyqtSignal(bool) + + def __init__(self, root, embedded=False, parent=None, **opts):   QWidget.__init__(self, parent)     layout = QVBoxLayout() @@ -44,8 +48,7 @@
  self.updateInProgress = False   self.tv = PathsTree(root, self)   - self.log = log - if not log: + if not embedded:   self.setWindowTitle(_('TortoiseHg Sync'))   self.resize(850, 550)   @@ -122,13 +125,19 @@
  self.outbutton, self.pushbutton,   self.emailbutton)   - cmd = cmdui.Widget(log) + cmd = cmdui.Widget(not embedded, self)   cmd.commandStarted.connect(self.commandStarted)   cmd.commandFinished.connect(self.commandFinished)   cmd.commandCanceling.connect(self.commandCanceled) + + cmd.makeLogVisible.connect(self.makeLogVisible) + cmd.output.connect(self.output) + cmd.progress.connect(self.progress) +   layout.addWidget(cmd) - cmd.setHidden(True) + cmd.setVisible(False)   self.cmd = cmd + self.embedded = embedded     self.reload()   if 'default' in self.paths: @@ -138,8 +147,9 @@
  def commandStarted(self):   for b in self.opbuttons:   b.setEnabled(False) - self.cmd.show_output(True) - self.cmd.setHidden(False) + if not self.embedded: + self.cmd.show_output(True) + self.cmd.setVisible(True)     def commandFinished(self, wrapper):   for b in self.opbuttons: @@ -271,8 +281,8 @@
  self.reload()   elif event.key() == Qt.Key_Escape:   if self.cmd.core.is_running(): - self.cmd.core.cancel() - elif not self.log: + self.cmd.cancel() + elif not self.embedded:   self.close()   else:   return super(SyncWidget, self).keyPressEvent(event) @@ -326,7 +336,7 @@
  self.run(cmdline)     def outclicked(self): - if self.log: + if self.embedded:   def outputnodes(ret, data):   if ret == 0:   nodes = data.splitlines()
 
19
20
21
22
 
23
24
25
 
126
127
128
129
 
130
131
132
 
19
20
21
 
22
23
24
25
 
126
127
128
 
129
130
131
132
@@ -19,7 +19,7 @@
   #from tortoisehg.hgqt.decorators import timeit   -from tortoisehg.hgqt import repomodel, thgrepo +from tortoisehg.hgqt import repomodel, thgrepo, cmdui  from tortoisehg.hgqt.i18n import _  from tortoisehg.hgqt.qtlib import geticon, getfont, configstyles, InfoMsgBox  from tortoisehg.hgqt.repowidget import RepoWidget @@ -126,7 +126,7 @@
    self.setCentralWidget(self.centralwidget)   - self.statusbar = QStatusBar(self) + self.statusbar = cmdui.ThgStatusBar(self)   self.setStatusBar(self.statusbar)     self.filterToolbar = tb = QToolBar(_("Filter Toolbar"), self)