Package Gnumed :: Package wxpython :: Module gmSoapSTCWidgets
[frames] | no frames]

Source Code for Module Gnumed.wxpython.gmSoapSTCWidgets

   1  # -*- coding: utf-8 -*- 
   2  __doc__ = """GNUmed StyledTextCtrl subclass for SOAP editing. 
   3   
   4  based on: 11/21/2003 - Jeff Grimmett (grimmtooth@softhome.net)""" 
   5  #================================================================ 
   6  __author__  = "K. Hilbert <Karsten.Hilbert@gmx.net>" 
   7  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
   8   
   9  import logging 
  10  import sys 
  11   
  12   
  13  import wx 
  14  import wx.stc 
  15   
  16   
  17  if __name__ == '__main__': 
  18          sys.path.insert(0, '../../') 
  19  from Gnumed.business import gmSoapDefs 
  20  from Gnumed.wxpython import gmKeywordExpansionWidgets 
  21  from Gnumed.wxpython.gmTextCtrl import cUnicodeInsertion_TextCtrlMixin 
  22   
  23   
  24  _log = logging.getLogger('gm.stc') 
  25   
  26  #================================================================ 
27 -class cWxTextCtrlCompatibility_StcMixin():
28
29 - def __init__(self, *args, **kwargs):
30 if not isinstance(self, wx.stc.StyledTextCtrl): 31 raise TypeError('[%s]: can only be applied to wx.stc.StyledTextCtrl, not [%s]' % (cWxTextCtrlCompatibility_StcMixin, self.__class__.__name__))
32 33 #-------------------------------------------------- 34 # wx.TextCtrl compatibility 35 #--------------------------------------------------
36 - def GetValue(self):
37 _log.debug('%s.GetValue() - %s', cWxTextCtrlCompatibility_StcMixin, self.__class__.__name__) 38 return self.GetText()
39 40 #--------------------------------------------------
41 - def SetValue(self, value):
42 _log.debug('%s.SetValue() - %s', cWxTextCtrlCompatibility_StcMixin, self.__class__.__name__) 43 return self.SetText(value)
44 45 #--------------------------------------------------
46 - def WriteText(self, value):
47 return self.InsertText(self.CurrentPos, value)
48 49 #--------------------------------------------------
50 - def GetLastPosition(self):
51 return self.Length
52 53 LastPosition = property(GetLastPosition, lambda x:x) 54 55 #--------------------------------------------------
56 - def GetNumberOfLines(self):
57 return self.LineCount
58 59 #--------------------------------------------------
60 - def GetLineText(self, line_no):
61 return self.GetLine(line_no)
62 63 #--------------------------------------------------
64 - def GetInsertionPoint(self):
65 return self.CurrentPos
66
67 - def SetInsertionPoint(self, position):
68 self.CurrentPos = position
69 70 InsertionPoint = property(GetInsertionPoint, SetInsertionPoint) 71 72 #--------------------------------------------------
73 - def ShowPosition(self, position):
74 #self.ScrollToLine(self.LineFromPosition(position)) 75 self.CurrentPos = position 76 self.EnsureCaretVisible()
77 78 #--------------------------------------------------
79 - def IsMultiLine(self):
80 return True
81 82 #--------------------------------------------------
83 - def PositionToXY(self, position):
84 try: 85 #return wx.stc.StyledTextCtrl.PositionToXY(position) # does not work 86 #return wx.TextAreaBase.PositionToXY(position) # does not work 87 return super(wx.TextAreaBase, self).PositionToXY(position) 88 except AttributeError: 89 # reimplement for wxPython 2.8, 90 # this is moot now, hwoever, since 2.8 returned an (x, y) tuple 91 return (True, self.GetColumn(position), self.LineFromPosition(position))
92 93 #--------------------------------------------------
94 - def Replace(self, start, end, replacement):
95 self.SetSelection(start, end) 96 self.ReplaceSelection(replacement) 97 wx.CallAfter(self.SetSelection, 0, 0)
98 99 #----------------------------------------------------------------------
100 -class cSoapSTC(cUnicodeInsertion_TextCtrlMixin, gmKeywordExpansionWidgets.cKeywordExpansion_TextCtrlMixin, cWxTextCtrlCompatibility_StcMixin, wx.stc.StyledTextCtrl):
101 102 _MARKER_ADM = 0 103 _MARKER_S = 1 104 _MARKER_O = 2 105 _MARKER_A = 3 106 _MARKER_P = 4 107 _MARKER_U = 5 108 _MARKER_LINE_BG_LIGHT_GREY = 31 109 110 _DEFINED_MARKERS_MASK = ( 111 _MARKER_ADM 112 | 113 _MARKER_S 114 | 115 _MARKER_O 116 | 117 _MARKER_A 118 | 119 _MARKER_P 120 | 121 _MARKER_U 122 | 123 _MARKER_LINE_BG_LIGHT_GREY 124 ) 125 126 _DEFINED_MARKER_NUMS = [ 127 _MARKER_ADM, 128 _MARKER_S, 129 _MARKER_O, 130 _MARKER_A, 131 _MARKER_P, 132 _MARKER_U, 133 _MARKER_LINE_BG_LIGHT_GREY 134 ] 135 _SOAP_MARKER_NUMS = [ 136 _MARKER_ADM, 137 _MARKER_S, 138 _MARKER_O, 139 _MARKER_A, 140 _MARKER_P, 141 _MARKER_U 142 ] 143 _SOAP2MARKER = { 144 None: _MARKER_ADM, 145 ' ': _MARKER_ADM, 146 '.': _MARKER_ADM, 147 's': _MARKER_S, 148 'o': _MARKER_O, 149 'a': _MARKER_A, 150 'p': _MARKER_P, 151 'u': _MARKER_U, 152 'S': _MARKER_S, 153 'O': _MARKER_O, 154 'A': _MARKER_A, 155 'P': _MARKER_P, 156 'U': _MARKER_U 157 } 158 _MARKER2SOAP = { 159 _MARKER_ADM: None, 160 _MARKER_S: 's', 161 _MARKER_O: 'o', 162 _MARKER_A: 'a', 163 _MARKER_P: 'p', 164 _MARKER_U: 'u' 165 } 166 _SOAPMARKER2BACKGROUND = { 167 _MARKER_ADM: False, 168 _MARKER_S: True, 169 _MARKER_O: False, 170 _MARKER_A: True, 171 _MARKER_P: False, 172 _MARKER_U: True 173 } 174
175 - def __init__(self, *args, **kwargs):
176 177 # normalize wxGlade output 178 if args[2] == '': 179 l_args = list(args) 180 l_args[2] = wx.DefaultPosition 181 args = tuple(l_args) 182 wx.stc.StyledTextCtrl.__init__(self, *args, **kwargs) 183 cWxTextCtrlCompatibility_StcMixin.__init__(self) 184 gmKeywordExpansionWidgets.cKeywordExpansion_TextCtrlMixin.__init__(self) 185 cUnicodeInsertion_TextCtrlMixin.__init__(self) 186 187 # wrapping and overflow 188 self.SetWrapMode(wx.stc.STC_WRAP_NONE) 189 # said to be problematic: 190 self.SetEdgeColumn(80) 191 self.SetEdgeColour('grey') 192 #self.SetEdgeMode(wx.stc.STC_EDGE_LINE) 193 self.SetEdgeMode(wx.stc.STC_EDGE_BACKGROUND) 194 195 # EOL style 196 self.SetEOLMode(wx.stc.STC_EOL_LF) 197 #self.SetViewEOL(1) # visual debugging 198 self.SetViewEOL(0) 199 200 # whitespace handling 201 #self.SetViewWhiteSpace(wx.stc.STC_WS_VISIBLEAFTERINDENT) # visual debugging 202 self.SetViewWhiteSpace(wx.stc.STC_WS_INVISIBLE) 203 #self.SetWhitespaceBackground(1, a_color) # 1 = override lexer 204 #self.SetWhitespaceForeground(1, a_color) # 1 = override lexer 205 206 # caret handling 207 #self.SetCaretLineBackground('light goldenrod yellow') 208 self.SetCaretLineBackground('khaki') 209 self.SetCaretLineVisible(1) 210 211 # margins 212 # left margin: 0 pixel widths 213 self.SetMarginLeft(0) 214 # margin 0: SOAP markers 215 self.SetMarginType(0, wx.stc.STC_MARGIN_SYMBOL) 216 self.SetMarginWidth(0, 16) 217 self.SetMarginMask(0, cSoapSTC._DEFINED_MARKERS_MASK) 218 # margin 1 and 2: additional 2-letter markers (not yet supported) 219 self.SetMarginType(1, wx.stc.STC_MARGIN_SYMBOL) 220 self.SetMarginMask(1, 0) 221 self.SetMarginWidth(1, 0) 222 self.SetMarginType(2, wx.stc.STC_MARGIN_SYMBOL) 223 self.SetMarginMask(2, 0) 224 self.SetMarginWidth(2, 0) 225 226 # markers 227 # can only use ASCII so far, so must make sure translations are ASCII: 228 self.MarkerDefine(cSoapSTC._MARKER_ADM, wx.stc.STC_MARK_CHARACTER + ord('.'), 'blue', 'white') 229 self.MarkerDefine(cSoapSTC._MARKER_S, wx.stc.STC_MARK_CHARACTER + ord(gmSoapDefs.soap_cat2l10n['s']), 'blue', 'grey96') 230 self.MarkerDefine(cSoapSTC._MARKER_O, wx.stc.STC_MARK_CHARACTER + ord(gmSoapDefs.soap_cat2l10n['o']), 'blue', 'white') 231 self.MarkerDefine(cSoapSTC._MARKER_A, wx.stc.STC_MARK_CHARACTER + ord(gmSoapDefs.soap_cat2l10n['a']), 'blue', 'grey96') 232 self.MarkerDefine(cSoapSTC._MARKER_P, wx.stc.STC_MARK_CHARACTER + ord(gmSoapDefs.soap_cat2l10n['p']), 'blue', 'white') 233 self.MarkerDefine(cSoapSTC._MARKER_U, wx.stc.STC_MARK_CHARACTER + ord(gmSoapDefs.soap_cat2l10n['u']), 'blue', 'grey96') 234 self.MarkerDefine(cSoapSTC._MARKER_LINE_BG_LIGHT_GREY, wx.stc.STC_MARK_BACKGROUND, 'grey96', 'grey96') 235 236 # unset hotkeys we want to re-define 237 #self.CmdKeyClear('t', wx.stc.STC_SCMOD_CTRL) # does not seem to work 238 self.__changing_SOAP_cat = False 239 self.__markers_of_prev_line = None 240 self.__ensure_has_all_soap_types = False 241 242 # we do our own popup menu 243 self.UsePopUp(0) 244 self.__build_context_menu() 245 246 # always keep one line of each of .SOAP around 247 self.SetText_from_SOAP() 248 249 self.__register_events() 250 251 # text expansion mixin 252 self.enable_keyword_expansions()
253 254 #------------------------------------------------------- 255 # SOAP-enhanced text setting 256 #-------------------------------------------------------
257 - def SetText(self, *args, **kwargs):
258 _log.debug('%s.SetText()', self.__class__.__name__) 259 wx.stc.StyledTextCtrl.SetText(self, *args, **kwargs)
260
261 - def AddText(self, *args, **kwargs):
262 _log.debug('%s.AddText()', self.__class__.__name__) 263 wx.stc.StyledTextCtrl.AddText(self, *args, **kwargs)
264
265 - def AddStyledText(self, *args, **kwargs):
266 _log.debug('%s.AddStyledText()', self.__class__.__name__) 267 wx.stc.StyledTextCtrl.AddStyledText(self, *args, **kwargs)
268
269 - def InsertText(self, *args, **kwargs):
270 _log.debug('%s.InsertText()', self.__class__.__name__) 271 wx.stc.StyledTextCtrl.InsertText(self, *args, **kwargs)
272 273 #-------------------------------------------------------
274 - def ReplaceSelection(self, text):
275 sel_start, sel_end = self.GetSelection() 276 start_line = self.LineFromPosition(sel_start) 277 end_line = start_line + text.count('\n') 278 start_line_soap_cat = self.MarkerGet(start_line) 279 #_log.debug(u'replacing @ pos %s-%s with %s lines (line %s to line %s)', sel_start, sel_end, text.count(u'\n'), start_line, end_line) 280 wx.stc.StyledTextCtrl.ReplaceSelection(self, text) 281 if start_line != end_line: 282 for target_line in range(start_line, end_line): 283 self.MarkerDelete(target_line, -1) 284 self.__set_markers_of_line(target_line, start_line_soap_cat)
285 286 #-------------------------------------------------------
287 - def ReplaceTarget(self, *args, **kwargs):
288 _log.debug('%s.ReplaceTarget()', self.__class__.__name__) 289 wx.stc.StyledTextCtrl.ReplaceTarget(self, *args, **kwargs)
290
291 - def ReplaceTargetRE(self, *args, **kwargs):
292 _log.debug('%s.ReplaceTargetRE()', self.__class__.__name__) 293 wx.stc.StyledTextCtrl.ReplaceTargetRE(self, *args, **kwargs)
294 295 #------------------------------------------------------- 296 # external API 297 #-------------------------------------------------------
298 - def SetText_from_SOAP(self, soap=None, sort_order=None):
299 # defaults 300 if soap is None: 301 #soap = {None: [u'']} # 'soap' will be added below by normalization 302 soap = {} 303 if sort_order is None: 304 sort_order = ['s', 'o', 'a', 'p', None, 'u'] 305 306 # normalize input 307 for cat in 'soap': 308 try: 309 soap[cat] 310 except KeyError: 311 soap[cat] = [''] 312 for cat in ['u', None]: 313 try: 314 soap[cat] 315 except KeyError: 316 soap[cat] = [] 317 if '.' in soap: 318 soap[None].extend(soap['.']) 319 del soap['.'] 320 if ' ' in soap: 321 soap[None].extend(soap[' ']) 322 del soap[' '] 323 324 # normalize sort order 325 for cat in 'soapu': 326 if cat not in sort_order: 327 sort_order.append(cat) 328 if None not in sort_order: 329 sort_order.append(None) 330 331 # sort and flatten 332 soap_lines = [] 333 line_categories = [] 334 for cat in sort_order: 335 lines = soap[cat] 336 if len(lines) == 0: 337 continue 338 for line in lines: 339 soap_lines.append(line.strip()) 340 line_categories.append(cat) 341 342 _log.debug('%s.SetText_from_SOAP(): 1 controlled use of .SetText() follows', self.__class__.__name__) 343 self.SetText('\n'.join(soap_lines)) 344 345 for idx in range(len(line_categories)): 346 self.set_soap_cat_of_line(idx, line_categories[idx])
347 348 #-------------------------------------------------------
349 - def GetText_as_SOAP(self):
350 lines = self.GetText().split('\n') 351 soap = {} 352 for line_idx in range(len(lines)): 353 cat = self.get_soap_cat_of_line(line_idx) 354 if cat == -1: 355 cat = 'u' 356 try: 357 soap[cat] 358 except KeyError: 359 soap[cat] = [] 360 soap[cat].append(lines[line_idx]) 361 return soap
362 363 soap = property(GetText_as_SOAP, lambda x:x) 364 365 #--------------------------------------------------------
366 - def _get_empty(self):
367 soap = self.GetText_as_SOAP() 368 for cat in soap: 369 if ''.join([ l.strip() for l in soap[cat] ]) != '': 370 return False 371 return True
372 373 empty = property(_get_empty, lambda x:x) 374 375 #-------------------------------------------------------
376 - def sort_by_SOAP(self, sort_order=None):
378 379 #-------------------------------------------------------
380 - def append_soap_line(self, soap_cat):
381 caret_pos = self.CurrentPos 382 self.GotoPos(self.Length) 383 self.AddText('\n') 384 self.set_soap_cat_of_line(self.LineCount, soap_cat)
385 386 #------------------------------------------------------- 387 # generic helpers 388 #-------------------------------------------------------
389 - def strip_trailing_whitespace_from_line(self, line):
390 line_text = self.GetLine(line) 391 line_start = self.PositionFromLine(line) 392 line_end = self.GetLineEndPosition(line) 393 self.SetTargetStart(line_start) 394 self.SetTargetEnd(line_end) 395 self.ReplaceTarget(line_text.rstrip())
396 397 #-------------------------------------------------------
398 - def caret_coords_in_stc(self):
399 return self.PointFromPosition(self.CurrentPos)
400 401 #-------------------------------------------------------
402 - def caret_coords_on_screen(self):
403 return self.ClientToScreen(self.caret_coords_in_stc())
404 405 #------------------------------------------------------- 406 # internal helpers 407 #-------------------------------------------------------
408 - def __build_context_menu(self):
409 410 # build menu 411 self.__popup_menu = wx.Menu(title = _('SOAP Editor Actions:')) 412 413 # sort 414 item = self.__popup_menu.Append(-1, _('&Sort lines'), _('Sort lines by SOAP category')) 415 self.Bind(wx.EVT_MENU, self.__on_sort_by_soap, item) 416 417 # expand keyword 418 item = self.__popup_menu.Append(-1, _('e&Xpand keyword'), _('Expand keyword / macro')) 419 self.Bind(wx.EVT_MENU, self.__on_expand_keyword, item) 420 421 # insert unicode 422 item = self.__popup_menu.Append(-1, _('Insert &Unicode'), _('Insert a unicode character')) 423 self.Bind(wx.EVT_MENU, self.__on_insert_unicode, item) 424 425 self.__popup_menu.AppendSeparator() 426 427 # undo 428 # redo 429 430 # submenu "line" 431 menu_line = wx.Menu() 432 433 item = menu_line.Append(-1, _('as &Subjective'), _('Set line to category "Subjective"')) 434 self.Bind(wx.EVT_MENU, self.__on_make_line_Soap, item) 435 item = menu_line.Append(-1, _('as &Objective'), _('Set line to category "Objective"')) 436 self.Bind(wx.EVT_MENU, self.__on_make_line_sOap, item) 437 item = menu_line.Append(-1, _('as &Assessment'), _('Set line to category "Assessment"')) 438 self.Bind(wx.EVT_MENU, self.__on_make_line_soAp, item) 439 item = menu_line.Append(-1, _('as &Plan'), _('Set line to category "Plan"')) 440 self.Bind(wx.EVT_MENU, self.__on_make_line_soaP, item) 441 item = menu_line.Append(-1, _('as &Unspecified'), _('Set line to category "unspecified"')) 442 self.Bind(wx.EVT_MENU, self.__on_make_line_soapU, item) 443 item = menu_line.Append(-1, _('as ad&Ministrative'), _('Set line to category "administrative"')) 444 self.Bind(wx.EVT_MENU, self.__on_make_line_soapADM, item) 445 menu_line.AppendSeparator() 446 item = menu_line.Append(-1, _('\u2192 &Clipboard'), _('Copy line to clipboard')) 447 self.Bind(wx.EVT_MENU, self.__on_line2clipboard, item) 448 item = menu_line.Append(-1, _('\u2192 +Clipboard+'), _('Add line to clipboard')) 449 self.Bind(wx.EVT_MENU, self.__on_add_line2clipboard, item) 450 # encrypt 451 452 # submenu "text" 453 menu_all = wx.Menu() 454 455 item = menu_all.Append(-1, _('\u2192 &Clipboard'), _('Copy content to clipboard')) 456 self.Bind(wx.EVT_MENU, self.__on_content2clipboard, item) 457 item = menu_all.Append(-1, _('\u2192 +Clipboard+'), _('Add content to clipboard')) 458 self.Bind(wx.EVT_MENU, self.__on_add_content2clipboard, item) 459 # ------ 460 # cut 461 # copy 462 # paste 463 # delete 464 # ------- 465 466 # selected region 467 self.__menu_selection = wx.Menu() 468 469 item = self.__menu_selection.Append(-1, _('\u2192 &Clipboard'), _('Copy selection to clipboard')) 470 self.Bind(wx.EVT_MENU, self.__on_region2clipboard, item) 471 item = self.__menu_selection.Append(-1, _('\u2192 +Clipboard+'), _('Add selection to clipboard')) 472 self.Bind(wx.EVT_MENU, self.__on_add_region2clipboard, item) 473 474 self.__popup_menu.Append(wx.NewId(), _('&Line ...'), menu_line) 475 self.__popup_menu.Append(wx.NewId(), _('&Text ...'), menu_all) 476 self.__popup_menu.Append(wx.NewId(), _('&Region ...'), self.__menu_selection)
477 478 #-------------------------------------------------------
479 - def __show_context_menu(self, position):
480 sel_start, sel_end = self.GetSelection() 481 sel_menu_id = self.__popup_menu.FindItem(_('&Region ...')) 482 if sel_start == sel_end: 483 self.__popup_menu.Enable(sel_menu_id, False) 484 else: 485 self.__popup_menu.Enable(sel_menu_id, True) 486 487 self.PopupMenu(self.__popup_menu, position)
488 489 #-------------------------------------------------------
490 - def __get_clipboard_text(self):
491 if wx.TheClipboard.IsOpened(): 492 _log.debug('clipboard already open') 493 return '' 494 if not wx.TheClipboard.Open(): 495 _log.debug('cannot open clipboard') 496 return '' 497 data_obj = wx.TextDataObject() 498 got_it = wx.TheClipboard.GetData(data_obj) 499 if not got_it: 500 return '' 501 return data_obj.Text
502 503 #------------------------------------------------------- 504 # context menu handlers 505 #-------------------------------------------------------
506 - def __on_expand_keyword(self, evt):
507 self.attempt_expansion(show_list_if_needed = True)
508 509 #-------------------------------------------------------
510 - def __on_insert_unicode(self, evt):
512 513 #-------------------------------------------------------
514 - def __on_content2clipboard(self, evt):
515 txt = self.GetText().strip() 516 if txt == '': 517 return 518 self.CopyText(len(txt), txt)
519 520 #-------------------------------------------------------
521 - def __on_add_content2clipboard(self, evt):
522 txt = self.GetText().strip() 523 if txt == '': 524 return 525 txt = self.__get_clipboard_text() + '\n' + txt 526 self.CopyText(len(txt), txt)
527 528 #-------------------------------------------------------
529 - def __on_region2clipboard(self, evt):
530 self.Copy()
531 532 #-------------------------------------------------------
533 - def __on_add_region2clipboard(self, evt):
534 region = self.GetTextRange(self.SelectionStart, self.SelectionEnd) 535 if region.strip() == '': 536 return 537 txt = self.__get_clipboard_text() + '\n' + region 538 self.CopyText(len(txt), txt)
539 540 #-------------------------------------------------------
541 - def __on_line2clipboard(self, evt):
542 txt = self.GetLine(self.CurrentLine).strip() 543 if txt == '': 544 return 545 self.CopyText(len(txt), txt)
546 547 #-------------------------------------------------------
548 - def __on_add_line2clipboard(self, evt):
549 txt = self.GetLine(self.CurrentLine).strip() 550 if txt == '': 551 return 552 txt = self.__get_clipboard_text() + '\n' + txt 553 self.CopyText(len(txt), txt)
554 555 #-------------------------------------------------------
556 - def __on_make_line_Soap(self, evt):
557 self.set_soap_cat_of_line(self.CurrentLine, 's') 558 wx.CallAfter(self.sort_by_SOAP)
559 560 #-------------------------------------------------------
561 - def __on_make_line_sOap(self, evt):
562 self.set_soap_cat_of_line(self.CurrentLine, 'o') 563 wx.CallAfter(self.sort_by_SOAP)
564 565 #-------------------------------------------------------
566 - def __on_make_line_soAp(self, evt):
567 self.set_soap_cat_of_line(self.CurrentLine, 'a') 568 wx.CallAfter(self.sort_by_SOAP)
569 570 #-------------------------------------------------------
571 - def __on_make_line_soaP(self, evt):
572 self.set_soap_cat_of_line(self.CurrentLine, 'p') 573 wx.CallAfter(self.sort_by_SOAP)
574 575 #-------------------------------------------------------
576 - def __on_make_line_soapU(self, evt):
577 self.set_soap_cat_of_line(self.CurrentLine, 'u') 578 wx.CallAfter(self.sort_by_SOAP)
579 580 #-------------------------------------------------------
581 - def __on_make_line_soapADM(self, evt):
582 self.set_soap_cat_of_line(self.CurrentLine, '.') 583 wx.CallAfter(self.sort_by_SOAP)
584 585 #-------------------------------------------------------
586 - def __on_sort_by_soap(self, evt):
587 self.sort_by_SOAP()
588 589 #------------------------------------------------------- 590 # marker related helpers 591 #-------------------------------------------------------
592 - def _clone_markers(self, source, target):
593 self.MarkerDelete(target, -1) 594 self.__set_markers_of_line(target, self.MarkerGet(source))
595 596 #-------------------------------------------------------
597 - def __set_markers_of_line(self, line, markers):
598 for marker_num in cSoapSTC._DEFINED_MARKER_NUMS: 599 if markers & (1 << marker_num): 600 self.MarkerAdd(line, marker_num)
601 602 #-------------------------------------------------------
603 - def get_soap_marker_of_line(self, line):
604 markers = self.MarkerGet(line) 605 for marker_num in cSoapSTC._SOAP_MARKER_NUMS: 606 if markers & (1 << marker_num): 607 return marker_num 608 609 return -1 # should only happen when deleting all lines -> STC empties out INCLUDING existing markers ...
610 611 #-------------------------------------------------------
612 - def get_soap_cat_of_line(self, line):
613 markers = self.MarkerGet(line) 614 for marker_num in cSoapSTC._SOAP_MARKER_NUMS: 615 if markers & (1 << marker_num): 616 return cSoapSTC._MARKER2SOAP[marker_num] 617 618 return -1 # should only happen when deleting all lines -> STC empties out INCLUDING existing markers ...
619 620 #-------------------------------------------------------
621 - def set_soap_cat_of_line(self, line, soap_category):
622 # remove all SOAP markers of this line 623 for marker_num in cSoapSTC._SOAP_MARKER_NUMS: 624 self.MarkerDelete(line, marker_num) 625 self.MarkerDelete(line, cSoapSTC._MARKER_LINE_BG_LIGHT_GREY) 626 # set desired marker 627 new_marker_num = cSoapSTC._SOAP2MARKER[soap_category] 628 self.MarkerAdd(line, new_marker_num) 629 if cSoapSTC._SOAPMARKER2BACKGROUND[new_marker_num]: 630 self.MarkerAdd(line, cSoapSTC._MARKER_LINE_BG_LIGHT_GREY) 631 return True
632 633 #-------------------------------------------------------
634 - def check_has_all_soap_types(self):
635 for marker_num in [ cSoapSTC._MARKER_S, cSoapSTC._MARKER_O, cSoapSTC._MARKER_A, cSoapSTC._MARKER_P ]: 636 if self.MarkerNext(0, (1 << marker_num)) == -1: 637 return False 638 return True
639 640 #-------------------------------------------------------
641 - def ensure_has_all_soap_types(self):
642 self.__ensure_has_all_soap_types = False 643 self.sort_by_SOAP()
644 645 #-------------------------------------------------------
646 - def marker_count(self, marker):
647 line_count = 0 648 line_w_marker = -1 649 while True: 650 line_w_marker = self.MarkerNext(line_w_marker + 1, (1 << marker)) 651 if line_w_marker == -1: 652 break 653 line_count += 1 654 return line_count
655 656 #-------------------------------------------------------
657 - def soap_cat_count(self, soap_category):
658 marker = cSoapSTC._SOAP2MARKER[soap_category] 659 return self.marker_count(marker)
660 661 #------------------------------------------------------- 662 # key handlers 663 #-------------------------------------------------------
664 - def __handle_delete_key(self, evt):
665 666 if evt.HasModifiers(): 667 # we only handle DELETE w/o modifiers so far 668 evt.Skip() 669 return False 670 671 sel_start, sel_end = self.GetSelection() 672 if sel_start != sel_end: 673 evt.Skip() 674 sel_start_line = self.LineFromPosition(sel_start) 675 sel_end_line = self.LineFromPosition(sel_end) 676 # within one line -> allow in any case 677 if sel_start_line == sel_end_line: 678 return 679 sel_start_soap_marker = self.get_soap_marker_of_line(sel_start_line) 680 sel_end_soap_marker = self.get_soap_marker_of_line(sel_end_line) 681 if sel_start_soap_marker == sel_end_soap_marker: 682 # across lines of the same SOAP type -> allow 683 return 684 self.__ensure_has_all_soap_types = True 685 return 686 687 curr_line = self.CurrentLine 688 if (curr_line + 1) == self.LineCount: # adjust for line index being 0-based 689 # we are on the last line, therefore we cannot end up 690 # pulling up a next line (and thereby remove the only 691 # line with a given SOAP category in case the last+1 692 # line would happen to be the only one of that category) 693 evt.Skip() 694 return False 695 696 # in last column 697 caret_pos = self.GetColumn(self.CurrentPos) 698 max_pos = self.LineLength(curr_line) - 1 699 if caret_pos < max_pos: 700 # DELETE _inside_ a line (as opposed to at the 701 # _end_ of one) will not pull up the next line 702 # so no special SOAP checking 703 evt.Skip() 704 return False 705 706 soap_marker_current_line = self.get_soap_marker_of_line(curr_line) 707 soap_marker_next_line = self.get_soap_marker_of_line(curr_line + 1) 708 if soap_marker_current_line == soap_marker_next_line: 709 # pulling up a line of the _same_ SOAP category 710 # is fine - and exactly what the user intended 711 # so allow that to happen (IOW no special DELETE 712 # handling) 713 evt.Skip() 714 return False 715 716 # now we have got 717 # - a DELETE 718 # - without modifier keys 719 # - _not_ on the last line 720 # - in the last column of the current line 721 # - but the next line is of a different SOAP category 722 # so, do NOT evt.Skip() - IOW, ignore this DELETE 723 return True
724 725 #-------------------------------------------------------
726 - def __handle_backspace_key(self, evt):
727 728 if evt.HasModifiers(): 729 # we only handle BACKSPACE w/o modifiers so far 730 evt.Skip() 731 return False 732 733 sel_start, sel_end = self.GetSelection() 734 if sel_start != sel_end: 735 evt.Skip() 736 sel_start_line = self.LineFromPosition(sel_start) 737 sel_end_line = self.LineFromPosition(sel_end) 738 # within one line -> allow in any case 739 if sel_start_line == sel_end_line: 740 return 741 sel_start_soap_marker = self.get_soap_marker_of_line(sel_start_line) 742 sel_end_soap_marker = self.get_soap_marker_of_line(sel_end_line) 743 if sel_start_soap_marker == sel_end_soap_marker: 744 # across lines of the same SOAP type -> allow 745 return 746 self.__ensure_has_all_soap_types = True 747 return 748 749 curr_line = self.LineFromPosition(self.CurrentPos) 750 if curr_line == 0: 751 # cannot BACKSPACE into line -1 anyway 752 evt.Skip() 753 return False 754 755 if self.GetColumn(self.CurrentPos) > 0: 756 # not in first column, so not BACKSPACing into previous line 757 evt.Skip() 758 return False 759 760 soap_marker_current_line = self.get_soap_marker_of_line(curr_line) 761 soap_marker_next_line = self.get_soap_marker_of_line(curr_line - 1) 762 if soap_marker_current_line == soap_marker_next_line: 763 # backspacing into previous line of the _same_ SOAP 764 # category is fine - and exactly what the user 765 # intended so allow that to happen (IOW no special 766 # DELETE handling) 767 evt.Skip() 768 return False 769 770 # now we have got 771 # - a BACKSPACE 772 # - without modifier keys 773 # - _not_ on the first line 774 # - in the first column of the current line 775 # - but the previous line is of a different SOAP category 776 # so, do NOT evt.Skip() - IOW, ignore this BACKSPACE 777 return True
778 779 #-------------------------------------------------------
780 - def __handle_return_key_down(self, evt):
781 # currently we always want to pass on the RETURN (but remember the markers) 782 evt.Skip() 783 if evt.HasModifiers(): 784 # we only handle RETURN w/o modifiers so far 785 self.__markers_of_prev_line = None 786 return 787 self.__markers_of_prev_line = self.MarkerGet(self.CurrentLine)
788 789 #-------------------------------------------------------
790 - def __handle_soap_category_key_down(self, key, line):
791 self.__changing_SOAP_cat = False 792 try: 793 soap_category = gmSoapDefs.l10n2soap_cat[key] 794 except KeyError: 795 if key.islower(): 796 key = key.upper() 797 else: 798 key = key.lower() 799 try: 800 soap_category = gmSoapDefs.l10n2soap_cat[key] 801 except KeyError: 802 return 803 self.set_soap_cat_of_line(line, soap_category) 804 wx.CallAfter(self.sort_by_SOAP)
805 806 #-------------------------------------------------------
807 - def __handle_menu_key_down(self, evt):
808 if wx.MAJOR_VERSION > 2: 809 evt.Skip() 810 return 811 # on wxp2 we need to explicitely handle WXK_MENU 812 # for the context menu to properly work on a key press 813 self.__show_context_menu(self.caret_coords_on_screen())
814 815 #-------------------------------------------------------
816 - def _on_context_menu_activated(self, evt):
817 menu_position = evt.GetPosition() 818 if menu_position == wx.DefaultPosition: 819 caret_pos_in_stc = self.PointFromPosition(self.CurrentPos) 820 caret_pos_on_screen = self.ClientToScreen(caret_pos_in_stc) 821 menu_position = caret_pos_on_screen 822 self.__show_context_menu(menu_position)
823 824 #------------------------------------------------------- 825 # event setup and handlers 826 #-------------------------------------------------------
827 - def __register_events(self):
828 # wxPython events 829 self.Bind(wx.EVT_KEY_DOWN, self._on_key_down) # happens before key gets into STC 830 #self.Bind(wx.EVT_CHAR, self._on_wx_char) # happens before char gets into STC 831 self.Bind(wx.EVT_CONTEXT_MENU, self._on_context_menu_activated) 832 833 # STC events 834 self.Bind(wx.stc.EVT_STC_CHARADDED, self._on_stc_char_added) 835 self.Bind(wx.stc.EVT_STC_CHANGE, self._on_stc_change)
836 837 #self.Bind(stc.EVT_STC_DO_DROP, self.OnDoDrop) 838 #self.Bind(stc.EVT_STC_DRAG_OVER, self.OnDragOver) 839 #self.Bind(stc.EVT_STC_START_DRAG, self.OnStartDrag) 840 #self.Bind(stc.EVT_STC_MODIFIED, self.OnModified) 841 842 #self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy) 843 844 #-------------------------------------------------------
845 - def _on_wx_char(self, evt):
846 evt.Skip()
847 848 #-------------------------------------------------------
849 - def _on_key_down(self, evt):
850 851 # CTRL-T has been pressed last, now another character has been pressed 852 if self.__changing_SOAP_cat: 853 self.__handle_soap_category_key_down(chr(evt.GetUnicodeKey()).lower(), self.CurrentLine) 854 # somehow put cursor into the changed (and possibly moved) line 855 return 856 857 key = evt.KeyCode 858 859 # ENTER 860 if key == wx.WXK_RETURN: 861 self.__handle_return_key_down(evt) 862 return 863 864 # BACKSPACE 865 if key == wx.WXK_BACK: 866 self.__handle_backspace_key(evt) 867 return 868 869 # DELETE 870 if key == wx.WXK_DELETE: 871 self.__handle_delete_key(evt) 872 return 873 874 # MENU 875 if key == wx.WXK_MENU: 876 self.__handle_menu_key_down(evt) 877 return 878 879 # CTRL-T: set Type 880 if key == ord('T'): 881 if evt.HasModifiers(): 882 if evt.CmdDown(): # CTRL-T or APPLE-T 883 self.__changing_SOAP_cat = True 884 return 885 886 evt.Skip() # make sure unhandled keys get to the STC
887 888 #-------------------------------------------------------
889 - def _on_stc_char_added(self, evt):
890 evt.Skip() 891 key = evt.GetKey() 892 if key == 10: 893 # we cannot simply transfer the markers of the previous 894 # line (where we pressed RETURN) into the current line 895 # (which appeared after the RETURN) because the STC handles 896 # creating the "new" line differently based on where in the 897 # previous line RETURN was pressed (!) -- if it happened 898 # to be in position 0 (at the start of the line) the previous 899 # line is pushed DOWN and an empty line is inserted BEFORE 900 # the previous line (likely an optimization) 901 # hence we need to remember the markers of the real previous 902 # line from _before_ the new line gets created and use that 903 # auto-set the markers of the new line... |-) 904 if self.__markers_of_prev_line is None: 905 return 906 self.__set_markers_of_line(self.CurrentLine - 1, self.__markers_of_prev_line) 907 self.__set_markers_of_line(self.CurrentLine, self.__markers_of_prev_line) 908 self.__markers_of_prev_line = None 909 return
910 911 #-------------------------------------------------------
912 - def _on_stc_change(self, evt):
913 if self.__ensure_has_all_soap_types: 914 wx.CallAfter(self.ensure_has_all_soap_types)
915 916 #------------------------------------------------------- 917 #------------------------------------------------------- 918 #------------------------------------------------------- 919 #------------------------------------------------------- 920 # unused: 921 #-------------------------------------------------------
922 - def OnDestroy(self, evt):
923 # This is how the clipboard contents can be preserved after 924 # the app has exited. 925 wx.TheClipboard.Flush() 926 evt.Skip()
927 928
929 - def OnStartDrag(self, evt):
930 #self.log.write("OnStartDrag: %d, %s\n" 931 # % (evt.GetDragAllowMove(), evt.GetDragText())) 932 933 if debug and evt.GetPosition() < 250: 934 evt.SetDragAllowMove(False) # you can prevent moving of text (only copy) 935 evt.SetDragText("DRAGGED TEXT") # you can change what is dragged
936 #evt.SetDragText("") # or prevent the drag with empty text 937 938
939 - def OnDragOver(self, evt):
940 #self.log.write( 941 # "OnDragOver: x,y=(%d, %d) pos: %d DragResult: %d\n" 942 # % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult()) 943 # ) 944 945 if debug and evt.GetPosition() < 250: 946 evt.SetDragResult(wx.DragNone) # prevent dropping at the beginning of the buffer
947 948
949 - def OnDoDrop(self, evt):
950 #self.log.write("OnDoDrop: x,y=(%d, %d) pos: %d DragResult: %d\n" 951 # "\ttext: %s\n" 952 # % (evt.GetX(), evt.GetY(), evt.GetPosition(), evt.GetDragResult(), 953 # evt.GetDragText())) 954 955 if debug and evt.GetPosition() < 500: 956 evt.SetDragText("DROPPED TEXT") # Can change text if needed
957 #evt.SetDragResult(wx.DragNone) # Can also change the drag operation, but it 958 # is probably better to do it in OnDragOver so 959 # there is visual feedback 960 961 #evt.SetPosition(25) # Can also change position, but I'm not sure why 962 # you would want to... 963 964
965 - def OnModified(self, evt):
966 #self.log.write("""OnModified 967 # Mod type: %s 968 # At position: %d 969 # Lines added: %d 970 # Text Length: %d 971 # Text: %s\n""" % ( self.transModType(evt.GetModificationType()), 972 # evt.GetPosition(), 973 # evt.GetLinesAdded(), 974 # evt.GetLength(), 975 # repr(evt.GetText()) )) 976 pass
977 978
979 - def transModType(self, modType):
980 st = "" 981 table = [(stc.STC_MOD_INSERTTEXT, "InsertText"), 982 (stc.STC_MOD_DELETETEXT, "DeleteText"), 983 (stc.STC_MOD_CHANGESTYLE, "ChangeStyle"), 984 (stc.STC_MOD_CHANGEFOLD, "ChangeFold"), 985 (stc.STC_PERFORMED_USER, "UserFlag"), 986 (stc.STC_PERFORMED_UNDO, "Undo"), 987 (stc.STC_PERFORMED_REDO, "Redo"), 988 (stc.STC_LASTSTEPINUNDOREDO, "Last-Undo/Redo"), 989 (stc.STC_MOD_CHANGEMARKER, "ChangeMarker"), 990 (stc.STC_MOD_BEFOREINSERT, "B4-Insert"), 991 (stc.STC_MOD_BEFOREDELETE, "B4-Delete") 992 ] 993 994 for flag,text in table: 995 if flag & modType: 996 st = st + text + " " 997 998 if not st: 999 st = 'UNKNOWN' 1000 1001 return st
1002 1003 #---------------------------------------------------------------------- 1004 #---------------------------------------------------------------------- 1005 #---------------------------------------------------------------------- 1006 if wx.Platform == '__WXMSW__': 1007 face1 = 'Arial' 1008 face2 = 'Times New Roman' 1009 face3 = 'Courier New' 1010 pb = 12 1011 else: 1012 face1 = 'Helvetica' 1013 face2 = 'Times' 1014 face3 = 'Courier' 1015 pb = 14 1016 1017 1018 _USE_PANEL = 1 1019
1020 -def runTest(frame, nb):
1021 if not _USE_PANEL: 1022 ed = p = cSoapSTC(nb, -1) 1023 1024 else: 1025 p = wx.Panel(nb, -1, style=wx.NO_FULL_REPAINT_ON_RESIZE) 1026 ed = cSoapSTC(p, -1, log) 1027 s = wx.BoxSizer(wx.HORIZONTAL) 1028 s.Add(ed, 1, wx.EXPAND) 1029 p.SetSizer(s) 1030 p.SetAutoLayout(True) 1031 1032 1033 #ed.SetBufferedDraw(False) 1034 #ed.StyleClearAll() 1035 #ed.SetScrollWidth(800) 1036 #ed.SetWrapMode(True) 1037 #ed.SetUseAntiAliasing(False) 1038 #ed.SetViewEOL(True) 1039 1040 #ed.CmdKeyClear(stc.STC_KEY_BACK, 1041 # stc.STC_SCMOD_CTRL) 1042 #ed.CmdKeyAssign(stc.STC_KEY_BACK, 1043 # stc.STC_SCMOD_CTRL, 1044 # stc.STC_CMD_DELWORDLEFT) 1045 1046 ed.SetText(demoText) 1047 1048 if wx.USE_UNICODE: 1049 import codecs 1050 decode = codecs.lookup("utf-8")[1] 1051 1052 ed.GotoPos(ed.GetLength()) 1053 ed.AddText("\n\nwx.StyledTextCtrl can also do Unicode:\n") 1054 uniline = ed.GetCurrentLine() 1055 unitext, l = decode('\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd - ' 1056 '\xd0\xbb\xd1\x83\xd1\x87\xd1\x88\xd0\xb8\xd0\xb9 ' 1057 '\xd1\x8f\xd0\xb7\xd1\x8b\xd0\xba \xd0\xbf\xd1\x80\xd0\xbe\xd0\xb3\xd1\x80\xd0\xb0\xd0\xbc\xd0\xbc\xd0\xb8\xd1\x80\xd0\xbe\xd0\xb2\xd0\xb0\xd0\xbd\xd0\xb8\xd1\x8f!\n\n') 1058 ed.AddText('\tRussian: ') 1059 ed.AddText(unitext) 1060 ed.GotoPos(0) 1061 #else: 1062 # #ed.StyleSetFontEncoding(stc.STC_STYLE_DEFAULT, wx.FONTENCODING_KOI8) 1063 # #text = u'\u041f\u0438\u0442\u043e\u043d - \u043b\u0443\u0447\u0448\u0438\u0439 \u044f\u0437\u044b\u043a \n\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f!' 1064 # #text = text.encode('koi8-r') 1065 # #ed.StyleSetFontEncoding(stc.STC_STYLE_DEFAULT, wx.FONTENCODING_BIG5) 1066 # #text = u'Python \u662f\u6700\u597d\u7684\u7de8\u7a0b\u8a9e\u8a00\uff01' 1067 # #text = text.encode('big5') 1068 # ed.GotoPos(ed.GetLength()) 1069 # ed.AddText('\n\n' + text) 1070 1071 ed.EmptyUndoBuffer() 1072 1073 # make some styles 1074 ed.StyleSetSpec(stc.STC_STYLE_DEFAULT, "size:%d,face:%s" % (pb, face3)) 1075 ed.StyleClearAll() 1076 ed.StyleSetSpec(1, "size:%d,bold,face:%s,fore:#0000FF" % (pb, face1)) 1077 ed.StyleSetSpec(2, "face:%s,italic,fore:#FF0000,size:%d" % (face2, pb)) 1078 ed.StyleSetSpec(3, "face:%s,bold,size:%d" % (face2, pb)) 1079 ed.StyleSetSpec(4, "face:%s,size:%d" % (face1, pb-1)) 1080 1081 # Now set some text to those styles... Normally this would be 1082 # done in an event handler that happens when text needs displayed. 1083 ed.StartStyling(98, 0xff) 1084 ed.SetStyling(6, 1) # set style for 6 characters using style 1 1085 1086 ed.StartStyling(190, 0xff) 1087 ed.SetStyling(20, 2) 1088 1089 ed.StartStyling(310, 0xff) 1090 ed.SetStyling(4, 3) 1091 ed.SetStyling(2, 0) 1092 ed.SetStyling(10, 4) 1093 1094 1095 # line numbers in the margin 1096 ed.SetMarginType(0, stc.STC_MARGIN_NUMBER) 1097 ed.SetMarginWidth(0, 22) 1098 ed.StyleSetSpec(stc.STC_STYLE_LINENUMBER, "size:%d,face:%s" % (pb-2, face1)) 1099 1100 # setup some markers 1101 ed.SetMarginType(1, stc.STC_MARGIN_SYMBOL) 1102 ed.MarkerDefine(0, stc.STC_MARK_ROUNDRECT, "#CCFF00", "RED") 1103 ed.MarkerDefine(1, stc.STC_MARK_CIRCLE, "FOREST GREEN", "SIENNA") 1104 ed.MarkerDefine(2, stc.STC_MARK_SHORTARROW, "blue", "blue") 1105 ed.MarkerDefine(3, stc.STC_MARK_ARROW, "#00FF00", "#00FF00") 1106 1107 # put some markers on some lines 1108 ed.MarkerAdd(17, 0) 1109 ed.MarkerAdd(18, 1) 1110 ed.MarkerAdd(19, 2) 1111 ed.MarkerAdd(20, 3) 1112 ed.MarkerAdd(20, 0) 1113 1114 1115 # and finally, an indicator or two 1116 ed.IndicatorSetStyle(0, stc.STC_INDIC_SQUIGGLE) 1117 ed.IndicatorSetForeground(0, wx.RED) 1118 ed.IndicatorSetStyle(1, stc.STC_INDIC_DIAGONAL) 1119 ed.IndicatorSetForeground(1, wx.BLUE) 1120 ed.IndicatorSetStyle(2, stc.STC_INDIC_STRIKE) 1121 ed.IndicatorSetForeground(2, wx.RED) 1122 1123 ed.StartStyling(836, stc.STC_INDICS_MASK) 1124 ed.SetStyling(10, stc.STC_INDIC0_MASK) 1125 ed.SetStyling(8, stc.STC_INDIC1_MASK) 1126 ed.SetStyling(10, stc.STC_INDIC2_MASK | stc.STC_INDIC1_MASK) 1127 1128 1129 # some test stuff... 1130 if debug: 1131 print("GetTextLength(): ", ed.GetTextLength(), len(ed.GetText())) 1132 print("GetText(): ", repr(ed.GetText())) 1133 print() 1134 print("GetStyledText(98, 104): ", repr(ed.GetStyledText(98, 104)), len(ed.GetStyledText(98, 104))) 1135 print() 1136 print("GetCurLine(): ", repr(ed.GetCurLine())) 1137 ed.GotoPos(5) 1138 print("GetCurLine(): ", repr(ed.GetCurLine())) 1139 print() 1140 print("GetLine(1): ", repr(ed.GetLine(1))) 1141 print() 1142 ed.SetSelection(25, 35) 1143 print("GetSelectedText(): ", repr(ed.GetSelectedText())) 1144 print("GetTextRange(25, 35): ", repr(ed.GetTextRange(25, 35))) 1145 print("FindText(0, max, 'indicators'): ", end=' ') 1146 print(ed.FindText(0, ed.GetTextLength(), "indicators")) 1147 if wx.USE_UNICODE: 1148 end = ed.GetLength() 1149 start = ed.PositionFromLine(uniline) 1150 print("GetTextRange(%d, %d): " % (start, end), end=' ') 1151 print(repr(ed.GetTextRange(start, end))) 1152 1153 1154 wx.CallAfter(ed.GotoPos, 0) 1155 return p
1156 1157 1158 #---------------------------------------------------------------------- 1159 overview = """\ 1160 <html><body> 1161 Once again, no docs yet. <b>Sorry.</b> But <a href="data/stc.h.html">this</a> 1162 and <a href="http://www.scintilla.org/ScintillaDoc.html">this</a> should 1163 be helpful. 1164 </body><html> 1165 """ 1166 1167 #=================================================== 1168 # main 1169 #--------------------------------------------------- 1170 if __name__ == '__main__': 1171 1172 if len(sys.argv) < 2: 1173 sys.exit() 1174 1175 if sys.argv[1] != 'test': 1176 sys.exit() 1177 1178 import wx.lib.colourdb 1179 1180 from Gnumed.pycommon import gmI18N 1181 gmI18N.activate_locale() 1182 gmI18N.install_domain(domain = 'gnumed') 1183 1184 #-----------------------------------------------
1185 - def test_stc():
1186 app = wx.PyWidgetTester(size = (600, 600)) 1187 wx.lib.colourdb.updateColourDB() 1188 #print wx.lib.colourdb.getColourList() 1189 app.SetWidget(cSoapSTC, -1, (100,50)) 1190 app.MainLoop() 1191 return True
1192 1193 # app = wx.PyWidgetTester(size = (200, 50)) 1194 # tc = cTextCtrl(app.frame, -1) 1195 # #tc.enable_keyword_expansions() 1196 # app.frame.Show(True) 1197 # app.MainLoop() 1198 # return True 1199 1200 #----------------------------------------------- 1201 test_stc() 1202