Modifying StyledTextCtrl actions

StyledTextCtrl sends two modified events, one before modification
(flag STC_MOD_BEFOREINSERT is true) and one after. I would like
to modify the text that is about to be changed, but I don't see how.
http://scintilla.sourceforge.net/ScintillaDoc.html#SCI_STYLESETCHANGEABLE
implies that I can't do what I want.

Am I right? And if so, what is the point of the pre-event?

Thanks for any clues,
Phil

I do not believe that you can change the content of the change, but
I've never tried. I believe that the pre-event is so that you can see
what is supposed to be happening and tell the STC to ignore the
change. Think of it like you are capturing an event in wx, and not
calling .Skip() to call other handlers, but doing nothing. If that's
the case, and you can discover everything you want from the first
event, you can get a replacement semantic by aborting the attempted
change, and programmatically changing the content yourself.

- Josiah

···

On Fri, Sep 12, 2008 at 3:14 PM, Phil Mayes <olivebr@olivebr.com> wrote:

StyledTextCtrl sends two modified events, one before modification
(flag STC_MOD_BEFOREINSERT is true) and one after. I would like
to modify the text that is about to be changed, but I don't see how.
Scintilla Documentation
implies that I can't do what I want.

Am I right? And if so, what is the point of the pre-event?

Thanks for any clues,

> StyledTextCtrl sends two modified events, one before modification
> (flag STC_MOD_BEFOREINSERT is true) and one after. I would like
> to modify the text that is about to be changed, but I don't see how.
> Scintilla Documentation
> implies that I can't do what I want.
>
> Am I right? And if so, what is the point of the pre-event?
>
> Thanks for any clues,

I do not believe that you can change the content of the change, but
I've never tried. I believe that the pre-event is so that you can see
what is supposed to be happening and tell the STC to ignore the
change. Think of it like you are capturing an event in wx, and not
calling .Skip() to call other handlers, but doing nothing. If that's
the case, and you can discover everything you want from the first
event, you can get a replacement semantic by aborting the attempted
change, and programmatically changing the content yourself.

- Josiah

Thanks, Josiah. It's a nice idea, but .Skip() (or not) makes no
difference. Test code below, in case anyone wants to play with it.

Phil

import wx
import wx.stc

bitText = [\
'wx.stc.STC_MOD_INSERTTEXT',
'wx.stc.STC_MOD_DELETETEXT',
'wx.stc.STC_MOD_CHANGESTYLE',
'wx.stc.STC_MOD_CHANGEFOLD',
'wx.stc.STC_PERFORMED_USER',
'wx.stc.STC_PERFORMED_UNDO',
'wx.stc.STC_PERFORMED_REDO',
'wx.stc.STC_LASTSTEPINUNDOREDO',
'wx.stc.STC_MOD_CHANGEMARKER',
'wx.stc.STC_MOD_BEFOREINSERT',
'wx.stc.STC_MOD_BEFOREDELETE',
]

mask = wx.stc.STC_MOD_INSERTTEXT\
      > wx.stc.STC_MOD_DELETETEXT\
      > wx.stc.STC_MOD_BEFOREINSERT\
      > 0

action = """Two EVT_STC_MODIFIED events are fired
but the STC_MOD_BEFOREINSERT event
appears to be informative only.

Using wx 2.8.7.1
Python 2.5.2
"""

class Dlg(wx.Dialog):
     def __init__(self):
         wx.Dialog.__init__(self, None, -1, u"StyledTextCtrl problem")
         sizer = wx.BoxSizer(wx.VERTICAL)
         sizer.Add(wx.StaticText(self, -1, action), 0, wx.ALL, 5)
         stc = wx.stc.StyledTextCtrl(self)
## stc.SetModEventMask(mask)
         stc.Bind(wx.stc.EVT_STC_MODIFIED, self.OnStcMod)
         stc.SetText("Some text in the StyledTextCtrl")
         sizer.Add(stc, 1, wx.ALL, 5)
         self.SetSizer(sizer)
         sizer.Fit(self)

     def OnStcMod(self, evt):
         print '==== EVT_STC_MODIFIED fired ===='
         text = evt.GetText()
         print 'GetText() length:',len(text),'text:',text
         bits = evt.GetModificationType()
         print 'GetModificationType() =>',hex(bits)
         if bits & wx.stc.STC_MOD_BEFOREINSERT:
             print 'before'
         for s in bitText:
             if bits & eval(s):
                 print '\t\t\t=',s

if __name__ == '__main__':
     app = wx.PySimpleApp()
     Dlg().ShowModal()

···

At 04:03 PM 9/13/2008, you wrote:

On Fri, Sep 12, 2008 at 3:14 PM, Phil Mayes <olivebr@olivebr.com> wrote:

I wouldn't have expected .Skip() to work. Looking at the Scintilla
documentation, it doesn't seem like modifications can be skipped. As
an alternative:
1. .Freeze() the control (so no visual updates occur)
2. let the event occur and the text be modified
3. use .GetText() to get the content of the stc
4. undo the change with stc.Undo()
5. use .GetText() to get the content of the stc before the change
6. compute the difference and do what you were going to do if you had
the chance to abort the change before
7. .Thaw() the control

···

On Sat, Sep 13, 2008 at 4:22 PM, Phil Mayes <olivebr@olivebr.com> wrote:

At 04:03 PM 9/13/2008, you wrote:

On Fri, Sep 12, 2008 at 3:14 PM, Phil Mayes <olivebr@olivebr.com> wrote:
> StyledTextCtrl sends two modified events, one before modification
> (flag STC_MOD_BEFOREINSERT is true) and one after. I would like
> to modify the text that is about to be changed, but I don't see how.
>
> Scintilla Documentation
> implies that I can't do what I want.
>
> Am I right? And if so, what is the point of the pre-event?
>
> Thanks for any clues,

I do not believe that you can change the content of the change, but
I've never tried. I believe that the pre-event is so that you can see
what is supposed to be happening and tell the STC to ignore the
change. Think of it like you are capturing an event in wx, and not
calling .Skip() to call other handlers, but doing nothing. If that's
the case, and you can discover everything you want from the first
event, you can get a replacement semantic by aborting the attempted
change, and programmatically changing the content yourself.

- Josiah

Thanks, Josiah. It's a nice idea, but .Skip() (or not) makes no
difference. Test code below, in case anyone wants to play with it.

Thanks Josiah, this looks promising.

Phil

···

At 10:03 AM 9/14/2008, Josiah Carlson wrote:

>> > StyledTextCtrl sends two modified events, one before modification
>> > (flag STC_MOD_BEFOREINSERT is true) and one after. I would like
>> > to modify the text that is about to be changed, but I don't see how.
[snip] Looking at the Scintilla
documentation, it doesn't seem like modifications can be skipped. As
an alternative:
1. .Freeze() the control (so no visual updates occur)
2. let the event occur and the text be modified
3. use .GetText() to get the content of the stc
4. undo the change with stc.Undo()
5. use .GetText() to get the content of the stc before the change
6. compute the difference and do what you were going to do if you had
the chance to abort the change before
7. .Thaw() the control