author | TK Soh <teekaysoh@yahoo.com> |
Sun, 06 Apr 2008 11:33:06 +0100 | |
changeset 1108 | 5a9d20cfcb29 |
parent 1039 | fb5b3786bf3f |
child 1113 | bf9563c56915 |
permissions | -rw-r--r-- |
171 | 1 |
# |
2 |
# A simple dialog to execute random command for TortoiseHg |
|
3 |
# |
|
4 |
# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com> |
|
5 |
# |
|
6 |
||
7 |
import pygtk |
|
8 |
pygtk.require("2.0") |
|
9 |
||
10 |
import gtk |
|
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
11 |
import gobject |
171 | 12 |
import pango |
269
41763e7da660
hggtk/cmd: run hg in unbuffered mode to display output a.s.a.p
TK Soh <teekaysoh@yahoo.com>
parents:
214
diff
changeset
|
13 |
import os |
171 | 14 |
import threading |
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
15 |
import Queue |
876
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
16 |
from hglib import HgThread, hgcmd_toq |
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
17 |
from shlib import set_tortoise_icon, get_system_times |
171 | 18 |
|
19 |
class CmdDialog(gtk.Dialog): |
|
608
0aedfe0954fa
hggtk/hgcmd: always show progress bar and cmdline
TK Soh <teekaysoh@yahoo.com>
parents:
607
diff
changeset
|
20 |
def __init__(self, cmdline, progressbar=True, width=520, height=400): |
404
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
21 |
title = 'hg ' + ' '.join(cmdline[1:]) |
171 | 22 |
gtk.Dialog.__init__(self, |
23 |
title=title, |
|
24 |
flags=gtk.DIALOG_MODAL, |
|
25 |
#buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) |
|
26 |
) |
|
455 | 27 |
|
28 |
set_tortoise_icon(self, 'hg.ico') |
|
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
29 |
self.cmdline = cmdline |
577
aba5048e5dac
hggtk/hgcmd: store return code from hg command
Steve Borho <steve@borho.org>
parents:
566
diff
changeset
|
30 |
self.returncode = None |
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
31 |
|
171 | 32 |
# construct dialog |
33 |
self.set_default_size(width, height) |
|
34 |
||
609
e381bdeaa92b
hggtk/hgcmd: rename 'OK' button to 'Close'
TK Soh <teekaysoh@yahoo.com>
parents:
608
diff
changeset
|
35 |
self._button_ok = gtk.Button("Close") |
615
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
36 |
self._button_ok.connect('clicked', self._on_ok_clicked) |
171 | 37 |
self.action_area.pack_end(self._button_ok) |
38 |
||
615
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
39 |
self.connect('delete-event', self._delete) |
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
40 |
self.connect('response', self._response) |
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
41 |
|
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
42 |
self.pbar = None |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
43 |
if progressbar: |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
44 |
self.last_pbar_update = 0 |
607
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
45 |
|
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
46 |
hbox = gtk.HBox() |
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
47 |
|
607
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
48 |
self.status_text = gtk.Label() |
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
49 |
self.status_text.set_text(" ".join(cmdline).replace("\n", " ")) |
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
50 |
self.status_text.set_alignment(0, 0.5) |
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
51 |
self.status_text.set_ellipsize(pango.ELLIPSIZE_END) |
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
52 |
hbox.pack_start(self.status_text, True, True, 3) |
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
53 |
|
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
54 |
# Create a centering alignment object |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
55 |
align = gtk.Alignment(0.0, 0.0, 1, 0) |
607
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
56 |
hbox.pack_end(align, False, False, 3) |
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
57 |
align.show() |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
58 |
|
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
59 |
# create the progress bar |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
60 |
self.pbar = gtk.ProgressBar() |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
61 |
align.add(self.pbar) |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
62 |
self.pbar.pulse() |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
63 |
self.pbar.show() |
607
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
64 |
|
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
65 |
self.vbox.pack_start(hbox, False, False, 3) |
06af164a9fba
hggtk/hgcmd: display cmdline next to progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
577
diff
changeset
|
66 |
|
171 | 67 |
scrolledwindow = gtk.ScrolledWindow() |
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
68 |
scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN) |
171 | 69 |
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) |
70 |
self.textview = gtk.TextView(buffer=None) |
|
71 |
self.textview.set_editable(False) |
|
72 |
self.textview.modify_font(pango.FontDescription("Monospace")) |
|
73 |
scrolledwindow.add(self.textview) |
|
74 |
self.textbuffer = self.textview.get_buffer() |
|
75 |
||
76 |
self.vbox.pack_start(scrolledwindow, True, True) |
|
401
9ab309fbc25c
hggtk: gtk threads and hgproc cleanup
Steve Borho <steve@borho.org>
parents:
395
diff
changeset
|
77 |
self.connect('map_event', self._on_window_map_event) |
171 | 78 |
|
531
5c5f39324c00
hggtk/hgcmd: cleaner method for closing dialog
Steve Borho <steve@borho.org>
parents:
527
diff
changeset
|
79 |
self.show_all() |
171 | 80 |
|
531
5c5f39324c00
hggtk/hgcmd: cleaner method for closing dialog
Steve Borho <steve@borho.org>
parents:
527
diff
changeset
|
81 |
def _on_ok_clicked(self, button): |
5c5f39324c00
hggtk/hgcmd: cleaner method for closing dialog
Steve Borho <steve@borho.org>
parents:
527
diff
changeset
|
82 |
""" Ok button clicked handler. """ |
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
83 |
self.response(gtk.RESPONSE_ACCEPT) |
171 | 84 |
|
615
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
85 |
def _delete(self, widget, event): |
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
86 |
return True |
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
87 |
|
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
88 |
def _response(self, widget, response_id): |
1039
fb5b3786bf3f
hggtk/hgcmd: fix potential lockup when called by other apps
TK Soh <teekaysoh@yahoo.com>
parents:
881
diff
changeset
|
89 |
if self.hgthread.isAlive(): |
615
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
90 |
widget.emit_stop_by_name('response') |
a5ef29ebbe08
hggtk/hgcmd: ignore close events while running
Steve Borho <steve@borho.org>
parents:
609
diff
changeset
|
91 |
|
171 | 92 |
def _on_window_map_event(self, event, param): |
404
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
93 |
self.hgthread = HgThread(self.cmdline[1:]) |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
94 |
self.hgthread.start() |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
95 |
self._button_ok.set_sensitive(False) |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
96 |
gobject.timeout_add(10, self.process_queue) |
171 | 97 |
|
98 |
def write(self, msg, append=True): |
|
99 |
msg = unicode(msg, 'iso-8859-1') |
|
100 |
if append: |
|
101 |
enditer = self.textbuffer.get_end_iter() |
|
102 |
self.textbuffer.insert(enditer, msg) |
|
103 |
else: |
|
104 |
self.textbuffer.set_text(msg) |
|
105 |
||
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
106 |
def process_queue(self): |
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
107 |
""" |
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
108 |
Handle all the messages currently in the queue (if any). |
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
109 |
""" |
527
e0e4fa338fc4
hggtk/hgthread: thread-safe dialog mechanism for GtkUi
Steve Borho <steve@borho.org>
parents:
483
diff
changeset
|
110 |
self.hgthread.process_dialogs() |
404
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
111 |
enditer = self.textbuffer.get_end_iter() |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
112 |
while self.hgthread.getqueue().qsize(): |
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
113 |
try: |
404
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
114 |
msg = self.hgthread.getqueue().get(0) |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
115 |
msg = unicode(msg, 'iso-8859-1') |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
116 |
self.textbuffer.insert(enditer, msg) |
214
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
117 |
except Queue.Empty: |
b2b08865b886
hggtk: use regular python thread to call popen in cmd dialog
TK Soh <teekaysoh@yahoo.com>
parents:
171
diff
changeset
|
118 |
pass |
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
119 |
self.update_progress() |
1039
fb5b3786bf3f
hggtk/hgcmd: fix potential lockup when called by other apps
TK Soh <teekaysoh@yahoo.com>
parents:
881
diff
changeset
|
120 |
if not self.hgthread.isAlive(): |
404
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
121 |
self._button_ok.set_sensitive(True) |
577
aba5048e5dac
hggtk/hgcmd: store return code from hg command
Steve Borho <steve@borho.org>
parents:
566
diff
changeset
|
122 |
self.returncode = self.hgthread.return_code() |
404
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
123 |
return False # Stop polling this function |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
124 |
else: |
92cbcf266f60
hggtk: switch hgcmd.py to HgThread
Steve Borho <steve@borho.org>
parents:
402
diff
changeset
|
125 |
return True |
171 | 126 |
|
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
127 |
def update_progress(self): |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
128 |
if not self.pbar: |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
129 |
return # progress bar not enabled |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
130 |
|
1039
fb5b3786bf3f
hggtk/hgcmd: fix potential lockup when called by other apps
TK Soh <teekaysoh@yahoo.com>
parents:
881
diff
changeset
|
131 |
if not self.hgthread.isAlive(): |
871
e4fe6fa0d24b
hggtk/hgcmd: hide progress bar upon completion
TK Soh <teekaysoh@yahoo.com>
parents:
615
diff
changeset
|
132 |
self.pbar.unmap() |
566
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
133 |
else: |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
134 |
# pulse the progress bar every ~100ms |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
135 |
tm = get_system_times()[4] |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
136 |
if tm - self.last_pbar_update < 0.100: |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
137 |
return |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
138 |
self.last_pbar_update = tm |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
139 |
self.pbar.pulse() |
7cba0c79391c
hggtk/hgcmd: add an activity progress bar
TK Soh <teekaysoh@yahoo.com>
parents:
531
diff
changeset
|
140 |
|
876
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
141 |
def run(cmdline=[], gui=True, **opts): |
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
142 |
if not gui: |
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
143 |
q = Queue.Queue() |
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
144 |
hgcmd_toq(None, q, *cmdline[1:]) |
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
145 |
return |
bfb494312954
hggtk/hgcmd: add nogui option
Steve Borho <steve@borho.org>
parents:
615
diff
changeset
|
146 |
|
608
0aedfe0954fa
hggtk/hgcmd: always show progress bar and cmdline
TK Soh <teekaysoh@yahoo.com>
parents:
607
diff
changeset
|
147 |
dlg = CmdDialog(cmdline) |
531
5c5f39324c00
hggtk/hgcmd: cleaner method for closing dialog
Steve Borho <steve@borho.org>
parents:
527
diff
changeset
|
148 |
dlg.connect('response', gtk.main_quit) |
401
9ab309fbc25c
hggtk: gtk threads and hgproc cleanup
Steve Borho <steve@borho.org>
parents:
395
diff
changeset
|
149 |
dlg.show_all() |
9ab309fbc25c
hggtk: gtk threads and hgproc cleanup
Steve Borho <steve@borho.org>
parents:
395
diff
changeset
|
150 |
gtk.gdk.threads_init() |
9ab309fbc25c
hggtk: gtk threads and hgproc cleanup
Steve Borho <steve@borho.org>
parents:
395
diff
changeset
|
151 |
gtk.gdk.threads_enter() |
9ab309fbc25c
hggtk: gtk threads and hgproc cleanup
Steve Borho <steve@borho.org>
parents:
395
diff
changeset
|
152 |
gtk.main() |
9ab309fbc25c
hggtk: gtk threads and hgproc cleanup
Steve Borho <steve@borho.org>
parents:
395
diff
changeset
|
153 |
gtk.gdk.threads_leave() |
171 | 154 |
|
155 |
if __name__ == "__main__": |
|
156 |
import sys |
|
608
0aedfe0954fa
hggtk/hgcmd: always show progress bar and cmdline
TK Soh <teekaysoh@yahoo.com>
parents:
607
diff
changeset
|
157 |
run(sys.argv) |
171 | 158 |