Going crazy with copy/paste problem

I have realy weird problem I'm going nuts about. I have list of items, and details for selected item are shown in TextCtrl (TE_MULTILINE|wx.TE_RICH on Windows Vista, with python 2.5.1 and wxPython 2.8)

After I copy text from TextCtrl and select some other item on the list (and TextCtrl content gets updated), when I try to paste the text into same TextCtrl sometimes paste inserts only empty line if copied text is single-line or multiple empty lines if text on clipboard is multiple-line. I can't recognize any pattern to this, except it's more (?) often when text contains international characters. Of course in plain editor text paste correctly before and after the problem.

Are there known bugs with copy-paste and TextCtrl or should I somehow "prepare" TextCtrl for unicode or TextCtrl "remembers" whether last text in it was unicode ... (see how weird it gets at 3am debugging this for two hours already)

Seriously, are there known related bugs? If not how do I debug copy/paste (or just paste, it seems)?

Best regards,
Igor

···

--
Igor Jese, igor@jeseonline.com
http://MockupScreens.com
http://SimpleProjectToDo.com

Igor Jese wrote:

I have realy weird problem I'm going nuts about. I have list of items, and details for selected item are shown in TextCtrl (TE_MULTILINE|wx.TE_RICH on Windows Vista, with python 2.5.1 and wxPython 2.8)

After I copy text from TextCtrl and select some other item on the list (and TextCtrl content gets updated), when I try to paste the text into same TextCtrl sometimes paste inserts only empty line if copied text is single-line or multiple empty lines if text on clipboard is multiple-line. I can't recognize any pattern to this, except it's more (?) often when text contains international characters. Of course in plain editor text paste correctly before and after the problem.

Are there known bugs with copy-paste and TextCtrl or should I somehow "prepare" TextCtrl for unicode or TextCtrl "remembers" whether last text in it was unicode ... (see how weird it gets at 3am debugging this for two hours already)

Seriously, are there known related bugs?

Not that I know of.

If not how do I debug copy/paste (or just paste, it seems)?

Try to narrow it down to a specific set of circumstances, and duplicate it in a small-as-possible app. http://wiki.wxpython.org/MakingSampleApps

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Igor Jese wrote:

I have created small app that reproduces the problem. Code is below.

Steps to reproduce the problem:
1. open app
2. click on "Add task" button twice
3. in "Notes" field enter text that has international characters
4. select different task on the list
5. click in "Notes" field and try to paste

What happens (at least at my system on Windows Vista, with python 2.5.1 and wxPython 2.8)) is that only new-line is pasted.

I see it on XP too, but the TextCtrl samples in the demo work fine. So work on narrowing it down further and figure out what your app does that the demo does not.

http://wiki.wxpython.org/MakingSampleApps

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Ok, I managed to reproduce this in really small example:
1. select the text in the text control (be sure to include international characters)
2. pick "second item" in radio
3. click in text control and try to paste

# -*- coding: iso-8859-2 -*-

import wx

class WinTest(wx.Frame):
     def __init__(self,parent,id,title):
         wx.Frame.__init__(self,parent,id,title)

         self.firstItem = u"Copy this: 'pokušaj nešto'"
         self.secondItem = "Try to paste here:"

         self.rb = wx.RadioBox(self,-1,"Two items",choices=['First item','Second item'])
         self.tc = wx.TextCtrl(self,-1,self.firstItem,style=wx.TE_RICH|wx.TE_MULTILINE)

         vbox = wx.BoxSizer(wx.VERTICAL)
         vbox.Add(self.rb,1,wx.EXPAND)
         vbox.Add(self.tc,1,wx.EXPAND)
         self.SetSizer(vbox)
         vbox.Fit(self)

         self.rb.Bind(wx.EVT_RADIOBOX,self.onRadio)
         #self.tc.Bind(wx.EVT_TEXT,self.onText)

         self.Show(True)

     def onRadio(self,e):
         if self.rb.GetSelection()==0:
             self.tc.SetValue(self.firstItem)
         else:
             self.tc.SetValue(self.secondItem)

     def onText(self,e):
         if self.rb.GetSelection()==0:
             self.firstItem = self.tc.GetValue()
         else:
             self.secondItem = self.tc.GetValue()

if __name__ == "__main__":
         app = wx.App()
         WinTest(None,-1,"Copy-paste test")
         app.MainLoop()

···

I see it on XP too, but the TextCtrl samples in the demo work fine. So work on narrowing it down further and figure out what your app does that the demo does not.

http://wiki.wxpython.org/MakingSampleApps

--
Igor Jese, igor@jeseonline.com

http://SimpleProjectToDo.com

Igor Jese wrote:

<div class="moz-text-flowed" style="font-family: -moz-fixed">Ok, I managed to reproduce this in really small example:
1. select the text in the text control (be sure to include international characters)
2. pick "second item" in radio
3. click in text control and try to paste

# -*- coding: iso-8859-2 -*-

import wx

class WinTest(wx.Frame):
def __init__(self,parent,id,title):
wx.Frame.__init__(self,parent,id,title)

self.firstItem = u"Copy this: 'pokušaj nešto'"
self.secondItem = "Try to paste here:"

self.rb = wx.RadioBox(self,-1,"Two items",choices=['First item','Second item'])
self.tc = wx.TextCtrl(self,-1,self.firstItem,style=wx.TE_RICH|wx.TE_MULTILINE)

vbox = wx.BoxSizer(wx.VERTICAL)
vbox.Add(self.rb,1,wx.EXPAND)
vbox.Add(self.tc,1,wx.EXPAND)
self.SetSizer(vbox)
vbox.Fit(self)

self.rb.Bind(wx.EVT_RADIOBOX,self.onRadio)
#self.tc.Bind(wx.EVT_TEXT,self.onText)

self.Show(True)

def onRadio(self,e):
if self.rb.GetSelection()==0:
self.tc.SetValue(self.firstItem)
else:
self.tc.SetValue(self.secondItem)

def onText(self,e):
if self.rb.GetSelection()==0:
self.firstItem = self.tc.GetValue()
else:
self.secondItem = self.tc.GetValue()

if __name__ == "__main__":
app = wx.App()
WinTest(None,-1,"Copy-paste test")
app.MainLoop()

I see it on XP too, but the TextCtrl samples in the demo work fine. So work on narrowing it down further and figure out what your app does that the demo does not.

http://wiki.wxpython.org/MakingSampleApps

This is weird. I can circumvent the problem if I select the text, copy it and paste it over the original BEFORE hitting the 2nd radio button. Then when I paste in the refreshed textctrl, it works.

I'm using wxPython 2.8.7.1 (unicode) on Windows XP SP3.

···

--------------
Mike Driscoll

Python Extension Building Network: http:\\www.pythonlibrary.org
Blog: http:\\blog.pythonlibrary.org

It works for me if you remove the wx.TE_RICH flag. Do you need that?
(But I don't know why this should be doing this).

···

On Wed, May 21, 2008 at 4:07 AM, Igor Jese <igor@jeseonline.com> wrote:

Ok, I managed to reproduce this in really small example:
1. select the text in the text control (be sure to include international
characters)
2. pick "second item" in radio
3. click in text control and try to paste

# -*- coding: iso-8859-2 -*-

import wx

class WinTest(wx.Frame):
   def __init__(self,parent,id,title):
       wx.Frame.__init__(self,parent,id,title)

       self.firstItem = u"Copy this: 'pokušaj nešto'"
       self.secondItem = "Try to paste here:"

       self.rb = wx.RadioBox(self,-1,"Two items",choices=['First
item','Second item'])
       self.tc =
wx.TextCtrl(self,-1,self.firstItem,style=wx.TE_RICH|wx.TE_MULTILINE)

       vbox = wx.BoxSizer(wx.VERTICAL)
       vbox.Add(self.rb,1,wx.EXPAND)
       vbox.Add(self.tc,1,wx.EXPAND)
       self.SetSizer(vbox)
       vbox.Fit(self)

       self.rb.Bind(wx.EVT_RADIOBOX,self.onRadio)
       #self.tc.Bind(wx.EVT_TEXT,self.onText)

       self.Show(True)

   def onRadio(self,e):
       if self.rb.GetSelection()==0:
           self.tc.SetValue(self.firstItem)
       else:
           self.tc.SetValue(self.secondItem)

   def onText(self,e):
       if self.rb.GetSelection()==0:
           self.firstItem = self.tc.GetValue()
       else:
           self.secondItem = self.tc.GetValue()

if __name__ == "__main__":
       app = wx.App()
       WinTest(None,-1,"Copy-paste test")
       app.MainLoop()

I see it on XP too, but the TextCtrl samples in the demo work fine. So
work on narrowing it down further and figure out what your app does that the
demo does not.

http://wiki.wxpython.org/MakingSampleApps

--
Igor Jese, igor@jeseonline.com
http://MockupScreens.com
http://SimpleProjectToDo.com
_______________________________________________
wxpython-users mailing list
wxpython-users@lists.wxwidgets.org
http://lists.wxwidgets.org/mailman/listinfo/wxpython-users

It works for me if you remove the wx.TE_RICH flag. Do you need that?
(But I don't know why this should be doing this).

Unfortunately I need Ctrl+backspace (and similar) and 64kb limit wouldn't do it either if I used "plain" TextCtrl. And on top of all that I plan to add formatting capability in near future. So I'm bound to somehow solve this or work around the problem :frowning:

Igor

···

--
Igor Jese, igor@jeseonline.com

http://SimpleProjectToDo.com

Igor,
Although I wasn't able to get a copy to work with your sample app yet, I
tried pasting your foreign words from your post into RichTextCtrl and it
displays the foreign characters correctly. Since you want to do formatting
capability eventually, maybe RichTextCtrl would be the way to go? Keep in
mind, it has some drawbacks, e.g. you cannot yet save to .RTF, and you can
not copy and paste formatting to and from other sources (so if you
copy a bold or
underlined word from a Word file, or from online, and paste it into a
RichTextCtrl
window it will be pasted as plain text).

By the way, this is a dumb question, but what about how your app is written
allows the output/error window to show up as a small frame instead of being
sent to my IDE's (Boa) error window? I've seen this in sample code before and
don't know what the setting for this is. Thanks.

Che

···

On Thu, May 22, 2008 at 4:01 PM, Igor Jese <igor@jeseonline.com> wrote:

It works for me if you remove the wx.TE_RICH flag. Do you need that?
(But I don't know why this should be doing this).

Unfortunately I need Ctrl+backspace (and similar) and 64kb limit wouldn't do
it either if I used "plain" TextCtrl. And on top of all that I plan to add
formatting capability in near future. So I'm bound to somehow solve this or
work around the problem :frowning:

Igor

Back to the problem, it seems pretty sure to me this is bug in wxPython. So what could I do to circumvent it until it gets fixed?

For now I can live without rich formatting and could try to go with 64K limit. So if I go without TE_RICH what's left is I need to implement standard text-editing shortcuts (eg. Ctrl+Backspace). Is there a list of what TE_RICH does exactly and is the source available?

Regards,
Igor

···

On Wed, 21 May 2008 10:07:46 +0200, Igor Jese <igor@jeseonline.com> wrote:

Ok, I managed to reproduce this in really small example:
1. select the text in the text control (be sure to include international characters)
2. pick "second item" in radio
3. click in text control and try to paste

# -*- coding: iso-8859-2 -*-

import wx

class WinTest(wx.Frame):
     def __init__(self,parent,id,title):
         wx.Frame.__init__(self,parent,id,title)

         self.firstItem = u"Copy this: 'pokušaj nešto'"
         self.secondItem = "Try to paste here:"

         self.rb = wx.RadioBox(self,-1,"Two items",choices=['First item','Second item'])
         self.tc = wx.TextCtrl(self,-1,self.firstItem,style=wx.TE_RICH|wx.TE_MULTILINE)

         vbox = wx.BoxSizer(wx.VERTICAL)
         vbox.Add(self.rb,1,wx.EXPAND)
         vbox.Add(self.tc,1,wx.EXPAND)
         self.SetSizer(vbox)
         vbox.Fit(self)

         self.rb.Bind(wx.EVT_RADIOBOX,self.onRadio)
         #self.tc.Bind(wx.EVT_TEXT,self.onText)

         self.Show(True)

     def onRadio(self,e):
         if self.rb.GetSelection()==0:
             self.tc.SetValue(self.firstItem)
         else:
             self.tc.SetValue(self.secondItem)

     def onText(self,e):
         if self.rb.GetSelection()==0:
             self.firstItem = self.tc.GetValue()
         else:
             self.secondItem = self.tc.GetValue()

if __name__ == "__main__":
         app = wx.App()
         WinTest(None,-1,"Copy-paste test")
         app.MainLoop()

I see it on XP too, but the TextCtrl samples in the demo work fine. So work on narrowing it down further and figure out what your app does that the demo does not.

http://wiki.wxpython.org/MakingSampleApps

--
Igor Jese, igor@jeseonline.com

http://SimpleProjectToDo.com

For now I can live without rich formatting and could try to go with 64K limit. So if I go without TE_RICH what's left is I need to implement standard text-editing shortcuts (eg. Ctrl+Backspace). Is there a list of what TE_RICH does exactly and is the source available?

I have quit using TE_RICH and implemented my own Ctrl+Backspace (Ctrl+arrows and Ctrl+C/V/X seem to work fine), but it's a crude workaround - no undo/redo for example.

In case someone needs the code, here it is:

     def onTextKeypress(self,e):
         if e.GetKeyCode()== wx.WXK_BACK and e.ControlDown()==True:
             txtCtrl = e.GetEventObject()
             right = txtCtrl.GetInsertionPoint()
             text = txtCtrl.GetValue()
             left = text.rfind(' ',0,right-1)
             if left==-1:
                 left = 0
             if text[right] == ' ' or left==0:
                 result = text[0:left] + text[right:len(text)]
             else:
                 result = text[0:left] + ' ' + text[right:len(text)]
             txtCtrl.SetValue(result)
             txtCtrl.SetInsertionPoint(left)
         else:
             e.Skip()

Regards,
Igor

Igor Jese wrote:

Ok, I think I see what the problem is. Copying to the clipboard does not actually copy anything, it just posts a promise to provide the data later when when it is asked for. When you change the value in the textctrl you are changing what it has to offer for the paste. You may have noticed that if you have more than one textctrl then there is no problem at all with copy/paste no matter if the text has international characters or not.

I see. It generates an interesting question: what do the "pro" applications do? In most serious applications you can "copy" then exit the application and then paste somewhere...

Maybe I should put something on clipboard immediately, can it be done somehow?

wx.TheClipboard.Flush() should do it, however be aware that it is possible for the memory needed for that data object could never be freed.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!