Here is an example of a basic SOAP widget using wxStyledTextCtrl
It has the four headers "Subjective" "Objective" etc. which are coloured red
and bold. Of course this can all be changed
to taste.
The user is not allowed to edit these headers (a few kludges to keep the cursor
away from this text, seems to work)
Pressing return puts the cursor to the right place on the next line. The text
will wrap if you try to go over the line.
The inbuilt autocompletion mechanism is used, currently with a fixed list but of course this can be anything grabbed from the
backend as we do now with the phrasewheel. Completions are coloured light blue.
Please test and comment.
Ian
------------------------------------------------------------------------
#!/usr/bin/env python
_ = lambda x: x
import string
from wxPython.wx import *
from wxPython.stc import *
STYLE_HEADER=1
STYLE_TEXT=2
STYLE_KEYWORD=3
completions = ['oesophagus', 'febrile', 'phlegmon', 'anaesthetic',
'phenoxybenzylpenicillin', 'penicillinamine']
class SOAPTextCtrl (wxStyledTextCtrl):
def __init__ (self, parent, id):
wxStyledTextCtrl.__init__ (self, parent, id, size = wxSize (400, 400))
id = self.GetId ()
self.SetWrapMode (wxSTC_WRAP_WORD)
self.StyleSetSpec (STYLE_HEADER, "fore:#7F11010,bold,face:Times,size:12")
self.StyleSetSpec (STYLE_KEYWORD, "fore:#4040B0")
self.SetEOLMode (wxSTC_EOL_LF)
self.SetMarginWidth (1, 0)
self.AutoCompStops ("()<>,.;:'\"[]{}\\|/? address@hidden&*")
self.autocompstr = ''
self.AutoCompSetSeparator (10)
self.__write_headings ()
EVT_KEY_DOWN (self, self.__keypressed)
EVT_LEFT_DOWN (self, self.__mouse_down)
EVT_STC_USERLISTSELECTION (self, id, self.__userlist)
def ClearAll (self):
wxStyledTextCtrl.ClearAll (self)
self.SetEOLMode (wxSTC_EOL_LF)
self.__write_headings ()
def __write_headings (self):
self.AddText ("""Subjective:
Objective:
Assessment:
Plan:
""")
self.StartStyling (0, 0xFF)
self.SetStyling (11, STYLE_HEADER)
self.StartStyling (13, 0xFF)
self.SetStyling (10, STYLE_HEADER)
self.StartStyling (25, 0xFF)
self.SetStyling (11, STYLE_HEADER)
self.StartStyling (38, 0xFF)
self.SetStyling (5, STYLE_HEADER)
self.GotoPos (9)
def __keypressed (self, event):
pos = self.GetCurrentPos ()
if self.AutoCompActive ():
event.Skip ()
else:
if event.KeyCode () in [WXK_RETURN, WXK_RIGHT, WXK_DELETE]:
if self.GetCharAt (pos) == 10: # we are at the end of a line
pos += 1
if self.GetStyleAt (pos) == STYLE_HEADER: # the next line is
a header
doclen = self.GetLength ()
while pos < doclen and self.GetCharAt (pos) != 10:
pos += 1 # go to the end of line
self.GotoPos (pos)
else:
event.Skip ()
else:
event.Skip ()
elif event.KeyCode () in [WXK_LEFT, WXK_BACK] and pos > 0 and
self.GetStyleAt (pos-1) == STYLE_HEADER:
# trying to move left onto a header, veto
pass
elif event.KeyCode () == WXK_UP:
line = self.LineFromPosition (pos)
col = self.GetColumn (pos)
if line > 0:
line -= 1
lineend = self.GetLineEndPosition (line)
pos = self.PositionFromLine (line) + col
if not (pos < lineend and self.GetStyleAt (pos) ==
STYLE_HEADER):
event.Skip ()
else:
self.GotoPos (lineend)
elif event.KeyCode () == WXK_DOWN:
line = self.LineFromPosition (pos)
col = self.GetColumn (pos)
line += 1
pos = self.PositionFromLine (line) + col
lineend = self.GetLineEndPosition (line)
if pos > 0 and not (pos < lineend and self.GetStyleAt (pos) ==
STYLE_HEADER):
event.Skip ()
else:
self.GotoPos (lineend)
else:
event.Skip ()
if event.KeyCode () < 255:
ch = string.lower (chr (event.KeyCode ()))
if ch in string.letters:
self.autocompstr += ch
if not self.AutoCompActive ():
clist = []
for i in completions:
if string.find (i, self.autocompstr) == 0:
clist.append (i)
if len (clist) > 0 and len (clist) < 7:
clist.sort ()
self.UserListShow (1, string.join (clist, '\n'))
else:
if ch != '\r':
self.autocompstr = ''
def __userlist (self, event):
pos = self.GetCurrentPos ()
self.SetTargetEnd (pos)
start = pos - len (self.autocompstr)
self.SetTargetStart (start)
text = event.GetText ()
self.ReplaceTarget (text)
self.StartStyling (start, 0xFF)
self.SetStyling (len (text), STYLE_KEYWORD)
self.GotoPos (start + len (text))
def __mouse_down (self, event):
pos = self.PositionFromPoint (event.GetPosition ())
if self.GetStyleAt (pos) == STYLE_HEADER:
doclen = self.GetLength ()
while pos < doclen and self.GetCharAt (pos) != 10:
pos += 1 # go to the end of line
self.GotoPos (pos)
else:
event.Skip ()
class MyFrame(wxFrame):
def __init__(self, title):
# begin wxGlade: MyFrame.__init__
wxFrame.__init__(self, None, wxNewId (), title)
self.text_ctrl_1 = SOAPTextCtrl(self, -1)
self.__do_layout()
# end wxGlade
def __do_layout(self):
# begin wxGlade: MyFrame.__do_layout
sizer_1 = wxBoxSizer(wxVERTICAL)
sizer_1.Add(self.text_ctrl_1, 1, wxEXPAND, 0)
self.SetAutoLayout(1)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
sizer_1.SetSizeHints(self)
self.Layout()
# end wxGlade
# end of class MyFrame
class MyApp (wxApp):
def OnInit (self):
frame = MyFrame ("Test SOAP")
frame.Show ()
return 1
app = MyApp (0)
app.MainLoop ()
------------------------------------------------------------------------
_______________________________________________
Gnumed-devel mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/gnumed-devel