# HG changeset patch # User Laurent Bessard # Date 1367828927 -7200 # Node ID 5f612651d2271fb052f6c94c30920f0a4d317db1 # Parent f4d08cea7774343d1a03edb3d2f78106fd5ef2e7 Fixed bug with margin cursor in StyledTextCtrl on Windows diff -r f4d08cea7774 -r 5f612651d227 Beremiz.py --- a/Beremiz.py Fri May 03 11:10:15 2013 +0200 +++ b/Beremiz.py Mon May 06 10:28:47 2013 +0200 @@ -147,6 +147,7 @@ from util.MiniTextControler import MiniTextControler from util.ProcessLogger import ProcessLogger from controls.LogViewer import LogViewer +from controls.CustomStyledTextCtrl import CustomStyledTextCtrl from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE from ProjectController import ProjectController, MATIEC_ERROR_MODEL, ITEM_CONFNODE @@ -255,18 +256,18 @@ if style != self.black_white: self.output.StartStyling(self.output.GetLength(), 0xff) - # Temporary deactivate read only mode on StyledTextCtrl for adding text - # It seems that text modifications, even programmatically, are disabled - # in StyledTextCtrl when read only is active + # Temporary deactivate read only mode on StyledTextCtrl for + # adding text. It seems that text modifications, even + # programmatically, are disabled in StyledTextCtrl when read + # only is active self.output.SetReadOnly(False) - self.output.AddText(s) + self.output.AppendText(s) self.output.SetReadOnly(True) if style != self.black_white: self.output.SetStyling(len(s), style) self.stack = [] self.lock.release() - self.output.ScrollToLine(self.output.GetLineCount()) self.output.Thaw() self.LastRefreshTime = gettime() try: @@ -289,9 +290,9 @@ wx.GetApp().Yield() def flush(self): - # Temporary deactivate read only mode on StyledTextCtrl for clearing text - # It seems that text modifications, even programmatically, are disabled - # in StyledTextCtrl when read only is active + # Temporary deactivate read only mode on StyledTextCtrl for clearing + # text. It seems that text modifications, even programmatically, are + # disabled in StyledTextCtrl when read only is active self.output.SetReadOnly(False) self.output.SetText("") self.output.SetReadOnly(True) @@ -412,7 +413,7 @@ self.SetAcceleratorTable(wx.AcceleratorTable(accels)) - self.LogConsole = wx.stc.StyledTextCtrl(id=ID_BEREMIZLOGCONSOLE, + self.LogConsole = CustomStyledTextCtrl(id=ID_BEREMIZLOGCONSOLE, name='LogConsole', parent=self.BottomNoteBook, pos=wx.Point(0, 0), size=wx.Size(0, 0)) self.LogConsole.Bind(wx.EVT_SET_FOCUS, self.OnLogConsoleFocusChanged) diff -r f4d08cea7774 -r 5f612651d227 c_ext/CFileEditor.py --- a/c_ext/CFileEditor.py Fri May 03 11:10:15 2013 +0200 +++ b/c_ext/CFileEditor.py Mon May 06 10:28:47 2013 +0200 @@ -8,7 +8,7 @@ from controls import CustomGrid, CustomTable from editors.ConfTreeNodeEditor import ConfTreeNodeEditor, SCROLLBAR_UNIT from util.BitmapLibrary import GetBitmap -from editors.TextViewer import GetCursorPos, faces +from controls.CustomStyledTextCtrl import CustomStyledTextCtrl, faces, GetCursorPos def AppendMenu(parent, help, id, kind, text): if wx.VERSION >= (2, 6, 0): @@ -30,12 +30,12 @@ "typedef", "typeid", "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while"] -class CppEditor(stc.StyledTextCtrl): +class CppEditor(CustomStyledTextCtrl): fold_symbols = 3 def __init__(self, parent, name, window, controler): - stc.StyledTextCtrl.__init__(self, parent, ID_CPPEDITOR, wx.DefaultPosition, + CustomStyledTextCtrl.__init__(self, parent, ID_CPPEDITOR, wx.DefaultPosition, wx.Size(-1, 300), 0) self.SetMarginType(1, stc.STC_MARGIN_NUMBER) diff -r f4d08cea7774 -r 5f612651d227 controls/CustomStyledTextCtrl.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/controls/CustomStyledTextCtrl.py Mon May 06 10:28:47 2013 +0200 @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import wx +import wx.stc + +if wx.Platform == '__WXMSW__': + faces = { 'times': 'Times New Roman', + 'mono' : 'Courier New', + 'helv' : 'Arial', + 'other': 'Comic Sans MS', + 'size' : 10, + } +else: + faces = { 'times': 'Times', + 'mono' : 'Courier', + 'helv' : 'Helvetica', + 'other': 'new century schoolbook', + 'size' : 12, + } + +def GetCursorPos(old, new): + if old == "": + return 0 + old_length = len(old) + new_length = len(new) + common_length = min(old_length, new_length) + i = 0 + for i in xrange(common_length): + if old[i] != new[i]: + break + if old_length < new_length: + if common_length > 0 and old[i] != new[i]: + return i + new_length - old_length + else: + return i + new_length - old_length + 1 + elif old_length > new_length or i < min(old_length, new_length) - 1: + if common_length > 0 and old[i] != new[i]: + return i + else: + return i + 1 + else: + return None + +class CustomStyledTextCtrl(wx.stc.StyledTextCtrl): + + def __init__(self, *args, **kwargs): + wx.stc.StyledTextCtrl(self, *args, **kwargs) + + self.Bind(wx.EVT_MOTION, self.OnMotion) + + def OnMotion(self, event): + if wx.Platform == '__WXMSW__': + if not event.Dragging(): + x, y = event.GetPosition() + margin_width = reduce( + lambda x, y: x + y, + [self.LogConsole.GetMarginWidth(i) + for i in xrange(3)], + 0) + if x <= margin_width: + self.LogConsole.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) + else: + self.LogConsole.SetCursor(wx.StockCursor(wx.CURSOR_IBEAM)) + else: + event.Skip() + + def AppendText(self, text): + last_position = self.GetLength() + current_selection = self.GetSelection() + self.GotoPos(last_position) + self.AddText(text) + if current_selection[0] != last_position: + self.SetSelection(*current_selection) + else: + self.ScrollToLine(self.GetLineCount()) diff -r f4d08cea7774 -r 5f612651d227 editors/TextViewer.py --- a/editors/TextViewer.py Fri May 03 11:10:15 2013 +0200 +++ b/editors/TextViewer.py Mon May 06 10:28:47 2013 +0200 @@ -31,6 +31,7 @@ from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD from plcopen.structures import ST_BLOCK_START_KEYWORDS, ST_BLOCK_END_KEYWORDS, IEC_BLOCK_START_KEYWORDS, IEC_BLOCK_END_KEYWORDS, LOCATIONDATATYPES from EditorPanel import EditorPanel +from controls.CustomStyledTextCtrl import CustomStyledTextCtrl, faces, GetCursorPos #------------------------------------------------------------------------------- # Textual programs Viewer class @@ -52,20 +53,6 @@ [ID_TEXTVIEWER, ID_TEXTVIEWERTEXTCTRL, ] = [wx.NewId() for _init_ctrls in range(2)] -if wx.Platform == '__WXMSW__': - faces = { 'times': 'Times New Roman', - 'mono' : 'Courier New', - 'helv' : 'Arial', - 'other': 'Comic Sans MS', - 'size' : 10, - } -else: - faces = { 'times': 'Times', - 'mono' : 'Courier', - 'helv' : 'Helvetica', - 'other': 'new century schoolbook', - 'size' : 12, - } re_texts = {} re_texts["letter"] = "[A-Za-z]" re_texts["digit"] = "[0-9]" @@ -79,29 +66,6 @@ SEARCH_RESULT_HIGHLIGHT: STC_PLC_SEARCH_RESULT, } -def GetCursorPos(old, new): - if old == "": - return 0 - old_length = len(old) - new_length = len(new) - common_length = min(old_length, new_length) - i = 0 - for i in xrange(common_length): - if old[i] != new[i]: - break - if old_length < new_length: - if common_length > 0 and old[i] != new[i]: - return i + new_length - old_length - else: - return i + new_length - old_length + 1 - elif old_length > new_length or i < min(old_length, new_length) - 1: - if common_length > 0 and old[i] != new[i]: - return i - else: - return i + 1 - else: - return None - def LineStartswith(line, symbols): return reduce(lambda x, y: x or y, map(lambda x: line.startswith(x), symbols), False) @@ -117,7 +81,7 @@ event(self, function) def _init_Editor(self, prnt): - self.Editor = wx.stc.StyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL, + self.Editor = CustomStyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL, parent=prnt, name="TextViewer", size=wx.Size(0, 0), style=0) self.Editor.ParentWindow = self diff -r f4d08cea7774 -r 5f612651d227 py_ext/PythonEditor.py --- a/py_ext/PythonEditor.py Fri May 03 11:10:15 2013 +0200 +++ b/py_ext/PythonEditor.py Mon May 06 10:28:47 2013 +0200 @@ -8,7 +8,7 @@ from plcopen.plcopen import TestTextElement from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD from editors.ConfTreeNodeEditor import ConfTreeNodeEditor -from editors.TextViewer import GetCursorPos, faces +from controls.CustomStyledTextCtrl import CustomStyledTextCtrl, faces, GetCursorPos [STC_PYTHON_ERROR, STC_PYTHON_SEARCH_RESULT] = range(15, 17) @@ -27,7 +27,7 @@ (_("Python code"), "_create_PythonCodeEditor")] def _create_PythonCodeEditor(self, prnt): - self.PythonCodeEditor = stc.StyledTextCtrl(id=ID_PYTHONEDITOR, parent=prnt, + self.PythonCodeEditor = CustomStyledTextCtrl(id=ID_PYTHONEDITOR, parent=prnt, name="TextViewer", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0) self.PythonCodeEditor.ParentWindow = self