tags:

views:

345

answers:

3

I have a textview and when something is pasted into it from the clipboard I need to intercept that text and do some preprocessing on it before it ends up in the textview.

I've tried listening to the "PasteClipboard" event which doesn't give me a way to modify the incoming text. and the "textview.Buffer.Changed" event which fires after the pasted text makes it into the textview.

Thanks in advance.

A: 

This may not be a help to you, but I am catching the WM_PASTE message in a custom control that implements TextBox. I get the GetText from the clipboard into a string variable and if it matches what I am looking for I make my changes to the variable and set the .Text to my variable and swallow the event so the textbox neer gets it. If it is not what I am looking for, but is allowed I just pass the event on with base.WndProc(ref m).

Sample:

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_PASTE)
    {
        string clipboardVin = Clipboard.GetText();
        string newVin = "";
        if (SelectionLength > 0)
        {
            newVin = Text.Replace(SelectedText, "");
        }
        else
        {
            newVin = Text;
        }
        newVin = newVin.Insert(SelectionStart, clipboardVin);
        if (!vinRegEx.IsMatch(newVin))
        {
            m.Result = new IntPtr(Convert.ToInt32(true));
            MessageBox.Show("The resulting text is not a valid VIN.", "Can Not Paste", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        else
        {
            base.WndProc(ref m);
        }
    }
    else
    {
        base.WndProc(ref m);
    }
}
Beaner
unfortunately that doesn't help me. I'm trying to do this on linux under gtk.
AvatarOfChronos
Should the c# tag be removed from this question?
Beaner
No, it's C#. GTK# is a .NET/Mono wrapper for the cross-platform GTK+ toolkit, like System.Windows.Forms is a wrapper for Win32 GUI.
mhutch
A: 

Doing some short googling, I found the following documentation on Gtk.TextBuffer and GTK alternative to .net WndProc in Mono. It appears that you might want to add the [GLib.ConnectBefore] attribute to your code to access GTK's WndProc method. Beaner's code above would probably work with slight modification for the GTK framework.

Chris
There's no direct equivalent of WndProc in GTK.
mhutch
+2  A: 

AFAIK your best option is to postprocess the text after it's been inserted - the InsertText event on the TextBuffer has arguments that tell you the position and size of the inserted text, so you can remove, process and re-insert it. You would of course want to avoid catching 1-char insertions (keystrokes) and your own re-insertions, but that's trivial.

The only other option I can think of is to re-implement paste support, by catching the paste key command, middle-click, etc. - but note that the command keys can be overridden in users' gtkrc files, so implementing this correctly could get hairy.

It might also be worth asking in the #gtk+ IRC channel on irc.gnome.org.

mhutch
Is there anything similar to WndProc in GTK? I haven't worked with Mono for a few years and I admit, I am a little rusty with the framework.
Chris
Not that I'm aware of, no. It's event-based ("signals" in C) all the way down. The Windows/X/Carbon message systems are hidden by the GDK platform abstraction.
mhutch
Of course, even if there were, you'd also need an equivalent of "WM_PASTE", which TBH is more the issue here.
mhutch
That said... in general in situations like this, the built-in behaviour is handled by a signal handler added by the widget itself. So to pre-empt built-in behaviours, you can put [GLib.ConnectBefore] on your signal handler to make it get connected *before* the built-in handler, then optionally set arg.RetVal to true if you want to prevent the signal propagating to the widget's handler. However, this only works if the EventArgs is a sublass of SignalArgs, which doesn't seem to be the case here.
mhutch