[Spambayes-checkins] spambayes/Outlook2000/dialogs
async_processor.py, NONE, 1.1.2.1
Mark Hammond
mhammond at users.sourceforge.net
Sun Aug 3 22:09:58 EDT 2003
- Previous message: [Spambayes-checkins] spambayes/Outlook2000/dialogs/resources
rcparser.py, 1.1.2.1, 1.1.2.2
- Next message: [Spambayes-checkins] spambayes/Outlook2000/dialogs dlgcore.py,
1.1.2.2, 1.1.2.3 opt_processors.py, 1.1.2.1,
1.1.2.2 processors.py, 1.1.2.2, 1.1.2.3 test_dialogs.py,
1.1.2.3, 1.1.2.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/spambayes/spambayes/Outlook2000/dialogs
In directory sc8-pr-cvs1:/tmp/cvs-serv15797
Added Files:
Tag: outlook-dialog-branch
async_processor.py
Log Message:
An async command processor that will do the threading magic.
--- NEW FILE: async_processor.py ---
# An async command processor
from dlgutils import *
import win32gui, win32api, win32con, commctrl
import win32process
import processors
try:
True, False
except NameError:
# Maintain compatibility with Python 2.2
True, False = 1, 0
IDC_START = 1100
IDC_PROGRESS = 1101
IDC_PROGRESS_TEXT = 1102
MYWM_SETSTATUS = win32con.WM_USER+11
MYWM_SETWARNING = win32con.WM_USER+12
MYWM_SETERROR = win32con.WM_USER+13
MYWM_FINISHED = win32con.WM_USER+14
# This is called from another thread - hence we need to jump through hoops!
class _Progress:
def __init__(self, processor):
self.hdlg = processor.window.hwnd
self.hprogress = processor.GetControl(processor.statusbar_id)
self.processor = processor
self.stopping = False
self.total_control_ticks = 100
self.current_stage = 0
self.set_stages( (("", 1.0),) )
def set_stages(self, stages):
self.stages = []
start_pos = 0.0
for name, prop in stages:
stage = name, start_pos, prop
start_pos += prop
self.stages.append(stage)
assert abs(start_pos-1.0) < 0.001, (
"Proportions must add to 1.0 (%r,%r,%r)" %
(start_pos, stages, start_pos-1.0))
def _next_stage(self):
if self.current_stage == 0:
win32api.PostMessage(self.hprogress, commctrl.PBM_SETRANGE, 0, MAKELPARAM(0,self.total_control_ticks))
win32api.PostMessage(self.hprogress, commctrl.PBM_SETSTEP, 1, 0)
win32api.PostMessage(self.hprogress, commctrl.PBM_SETPOS, 0, 0)
self.current_control_tick = 0
self.current_stage += 1
assert self.current_stage <= len(self.stages)
def _get_current_stage(self):
return self.stages[self.current_stage-1]
def set_max_ticks(self, m):
self._next_stage()
self.current_stage_tick = 0
self.current_stage_max = m
def tick(self):
self.current_stage_tick += 1
# Calc how far through this stage.
this_prop = float(self.current_stage_tick) / self.current_stage_max
# How far through the total.
stage_name, start, end = self._get_current_stage()
# Calc the perc of the total control.
stage_name, start, prop = self._get_current_stage()
total_prop = start + this_prop * prop
# How may ticks is this on the control
control_tick = int(total_prop * self.total_control_ticks)
#print "Tick", self.current_stage_tick, "is", this_prop, "through the stage,", total_prop, "through the total - ctrl tick is", control_tick
while self.current_control_tick < control_tick:
self.current_control_tick += 1
#print "ticking control", self.current_control_tick
win32api.PostMessage(self.hprogress, commctrl.PBM_STEPIT, 0, 0)
def _get_stage_text(self, text):
stage_name, start, end = self._get_current_stage()
if stage_name:
text = stage_name + ": " + text
return text
def set_status(self, text):
self.processor.progress_status = self._get_stage_text(text)
win32api.PostMessage(self.hdlg, MYWM_SETSTATUS)
def warning(self, text):
self.processor.progress_warning = self._get_stage_text(text)
win32api.PostMessage(self.hdlg, MYWM_SETWARNING)
def error(self, text):
self.processor.progress_error = self._get_stage_text(text)
win32api.PostMessage(self.hdlg, MYWM_SETERROR)
def request_stop(self):
self.stopping = True
def stop_requested(self):
return self.stopping
class AsyncCommandProcessor(processors.CommandButtonProcessor):
def __init__(self, window, control_ids, func, start_text, stop_text, disable_ids):
processors.CommandButtonProcessor.__init__(self, window, control_ids[:1], func, ())
self.progress_status = ""
self.progress_error = ""
self.progress_warning = ""
self.running = False
self.statusbar_id = control_ids[1]
self.statustext_id = control_ids[2]
self.process_start_text = start_text
self.process_stop_text = stop_text
dids = self.disable_while_running_ids = []
for id in disable_ids.split():
dids.append(window.manager.dialog_parser.ids[id])
def Init(self):
win32gui.ShowWindow(self.GetControl(self.statusbar_id), win32con.SW_HIDE)
self.SetStatusText("")
def GetMessages(self):
return [MYWM_SETSTATUS, MYWM_SETWARNING, MYWM_SETERROR, MYWM_FINISHED]
def SetEnabledStates(self, enabled):
for id in self.disable_while_running_ids:
win32gui.EnableWindow(self.GetControl(id), enabled)
def OnMessage(self, msg, wparam, lparam):
if msg == MYWM_SETSTATUS:
self.OnProgressStatus(wparam, lparam)
elif msg == MYWM_SETWARNING:
self.OnProgressWarning(wparam, lparam)
elif msg == MYWM_SETERROR:
self.OnProgressError(wparam, lparam)
elif msg == MYWM_FINISHED:
self.OnFinished(wparam, lparam)
else:
raise RuntimeError, "Not one of my messages??"
def OnFinished(self, wparam, lparam):
self.seen_finished = True
wasCancelled = wparam
self.SetEnabledStates(True)
win32gui.SendMessage(self.GetControl(), win32con.WM_SETTEXT,
0, self.process_start_text)
win32gui.ShowWindow(self.GetControl(self.statusbar_id), win32con.SW_HIDE)
if wasCancelled:
self.SetStatusText("Cancelled")
def SetStatusText(self, text):
win32gui.SendMessage(self.GetControl(self.statustext_id),
win32con.WM_SETTEXT,
0, text)
def OnProgressStatus(self, wparam, lparam):
self.SetStatusText(self.progress_status)
def OnProgressError(self, wparam, lparam):
self.SetStatusText(self.progress_error)
win32gui.MessageBox(self.window.hwnd,
self.progress_error, "SpamBayes",
win32con.MB_OK | win32con.MB_ICONEXCLAMATION)
if not self.running and not self.seen_finished:
self.OnFinished(0,0)
def OnProgressWarning(self, wparam, lparam):
pass
def OnClicked(self, id):
self.StartProcess()
def StartProcess(self):
if self.running:
self.progress.request_stop()
else:
# Do anything likely to fail before we screw around with the
# control states - this way the dialog doesn't look as 'dead'
progress=_Progress(self)
# Now screw around with the control states, restored when
# the thread terminates.
self.SetEnabledStates(False)
win32gui.SendMessage(self.GetControl(),
win32con.WM_SETTEXT,
0, self.process_stop_text)
win32gui.SendMessage(self.GetControl(self.statustext_id),
win32con.WM_SETTEXT, 0, "")
win32gui.ShowWindow(self.GetControl(self.statusbar_id),
win32con.SW_SHOW)
# Local function for the thread target that notifies us when finished.
def thread_target(h, progress):
try:
self.progress = progress
self.seen_finished = False
self.running = True
# Drop my thread priority, so outlook can keep repainting
# and doing its stuff without getting stressed.
import win32process, win32api
THREAD_PRIORITY_BELOW_NORMAL=-1
win32process.SetThreadPriority(win32api.GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL)
self.func( self.window.manager, progress)
finally:
win32api.PostMessage(h, MYWM_FINISHED, self.progress.stop_requested())
self.running = False
self.progress = None
# back to the program :)
import threading
t = threading.Thread(target=thread_target, args =(self.window.hwnd, progress))
t.start()
if __name__=='__main__':
# Test my "multi-stage" code
class HackProgress(_Progress):
def __init__(self): # dont use dlg
self.hprogress = self.hdlg = 0
self.dlg = None
self.stopping = False
self.total_control_ticks = 100
self.current_stage = 0
self.set_stages( (("", 1.0),) )
p = HackProgress()
p.set_max_ticks(10)
for i in range(10):
p.tick()
p = HackProgress()
stages = ("Stage 1", 0.2), ("Stage 2", 0.8)
p.set_stages(stages)
# Do stage 1
p.set_max_ticks(10)
for i in range(10):
p.tick()
# Do stage 2
p.set_max_ticks(1000)
for i in range(1000):
p.tick()
print "Done!"
- Previous message: [Spambayes-checkins] spambayes/Outlook2000/dialogs/resources
rcparser.py, 1.1.2.1, 1.1.2.2
- Next message: [Spambayes-checkins] spambayes/Outlook2000/dialogs dlgcore.py,
1.1.2.2, 1.1.2.3 opt_processors.py, 1.1.2.1,
1.1.2.2 processors.py, 1.1.2.2, 1.1.2.3 test_dialogs.py,
1.1.2.3, 1.1.2.4
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Spambayes-checkins
mailing list