lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Pasting between multiline edit controls


From: Vadim Zeitlin
Subject: Re: [lmi] Pasting between multiline edit controls
Date: Wed, 11 Nov 2015 15:50:18 +0100

On Tue, 10 Nov 2015 18:46:59 +0000 Greg Chicares <address@hidden> wrote:

GC> But I can't get the paste handler to work. Let me present my patch and ask
GC> you to tell me what I'm doing wrong.

 Hello,

 The problem is that wxClipboardTextEvent::GetEventObject() returns the
wxTextCtrl on which Paste() is called by Skeleton::UponTestPasting() and
not its containing InputSequenceEntry as your handler assumes, so the
solution is to replace this part

GC>  void Skeleton::UponPaste(wxClipboardTextEvent& event)
GC>  {
GC>      event.Skip();
GC> 
GC> -    wxTextCtrl* t = dynamic_cast<wxTextCtrl*>(event.GetEventObject());
GC> -    if(!t)
GC> +    InputSequenceEntry* z = 
dynamic_cast<InputSequenceEntry*>(event.GetEventObject());
GC> +    if(!z)
GC>          {
GC>          return;
GC>          }
GC> 
GC> +    wxTextCtrl& t = z->text_ctrl();

with just this:

---------------------------------- >8 --------------------------------------
@@ -1032,6 +1043,11 @@ void Skeleton::UponPaste(wxClipboardTextEvent& event)
         return;
         }

+    if(!dynamic_cast<InputSequenceEntry*>(t->GetParent()))
+        {
+        return;
+        }
+
     std::string const s(ClipboardEx::GetText());
     if(s.empty())
         {
---------------------------------- >8 --------------------------------------

i.e. continue casting the event object to wxTextCtrl and then check if this
wxTextCtrl is actually part of an InputSequenceEntry.

 To be slightly more robust, we could check if the text control has
InputSequenceEntry among its parents recursively, this would allow the code
continue to work even if InputSequenceEntry is later refactored and doesn't
have wxTextCtrl as its direct children any more in the future, which is
possible although unlikely. I would still prefer to just go with my
original proposal instead and move this handler to InputSequenceEntry
itself, then we certainly wouldn't forget to update it if such refactoring
ever happens.


 Alternatively, we could make your original code work by catching the
wxEVT_TEXT_PASTE event from its "text_" in InputSequenceEntry and resending
it as wxEVT_TEXT_PASTE from the composite control itself. For consistency,
we would also need to override Paste() in InputSequenceEntry and forward it
to "text_" and call this method on InputSequenceEntry itself in the test.
AFAICS this would work but I still would prefer to just encapsulate pasting
handling in InputSequenceEntry itself rather than go to all these lengths
to make it appear as if it were a wxTextCtrl.

 Unfortunately there is no simple nor reliable way (and by using "nor" I
want to emphasize that you can't get either simplicity nor reliability, let
alone both of them) to make a composite control appear as some other
control that it contains, wxWidgets API wasn't really built with delegation
in mind and while wxCompositeWindow<> makes it possible for a composite
window to behave like a wxWindow, there is no wxCompositeTextCtrl that
would make it behave like a wxTextCtrl. And it would be quite difficult to
create such class. So IMHO it would be better to not even try and just
accept that while InputSequenceEntry contains a text and a button, it is
not a text nor a button itself.

 BTW, I think it would make sense to derive InputSequenceEntry from
wxCompositeWindow<>. This would allow calls setting colours or font or
tooltip for InputSequenceEntry to affect both the text and the button
inside it and would also make InputSequenceEntry behave as a single
control for the purpose of focus tracking which could avoid surprises
similar to the above one in the future. I think the only reason this class
doesn't inherit from wxCompositeWindow<> is that it had been written in
July 2010, i.e. 6 months before wxCompositeWindow<> which was created.


GC> @@ -1086,26 +1101,27 @@
GC> 
GC>  void Skeleton::UponTestPasting(wxCommandEvent&)
GC>  {
GC> -    wxTextCtrl* t = new wxTextCtrl(frame_, wxID_ANY, "Testing...");
GC> -    LMI_ASSERT(t);
GC> +    InputSequenceEntry* z = new InputSequenceEntry(frame_, wxID_ANY, 
"Testing...");
GC> +    LMI_ASSERT(z);
GC> +    wxTextCtrl& t = z->text_ctrl();
...
GC> -    t->Destroy();
GC> +    t.Destroy();
GC>      status() << "Pasting test finished." << std::flush;
GC>  }

 There is also another small problem here: the code should destroy the
entire test InputSequenceEntry and not just the wxTextCtrl part of it, so
the last added line should be "z->Destroy()". With these two small fixes
everything seems to work on me, see the attached updated patch.

 Please let me know if I should make further patches to

1. Move this event handler to InputSequenceEntry itself.
2. Move the test to the GUI test suite.

 Thanks,
VZ

Attachment: fixed-paste.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]