Re: Signal help




On Sep 8, 2004, at 5:27 PM, Charles Josephs wrote:

1)  I have a TextView widget with a TextBuffer.  I wish to catch all
attempts the user makes to change the TextBuffer before the change is
applied and do some processing on it.  Depending on the results of my
processing, I want to either block the attempt silently or let it
through.  This is somewhat based on the changes they are trying to
make and other external conditions.  I'm held back here by not knowing
how to catch such an attempt to change the buffer and either stop it
or let it through optionally.  I think it'd be simple, but the right
way to do it eludes me.

the insert-text signal is fired before the change is actually applied to the buffer, and it's given the text. there doesn't seem to be a way to modify the text or cancel the operation but you can use other GObject techniques to control whether the handler that does the actual insertion gets called. one technique would be to override in a subclass, like this:

  use Glib::Object::Subclass
      'Gtk2::TextBuffer',
      signals {
          insert_text => sub {
              # we get passed the length; all we really need to do is
              # pass it on, but since scalars know their length, i'll
              # ignore it.
              my ($self, $iter, $string) = @_;
              # do any custom stuff here...
              $string = mangle_text ($string);
              if ($string) {
                  # call the base class with the modified text:
$self->signal_chain_from_overridden ($iter, $string, length($string));
              } else {
                  # we apparently don't want any text to get inserted,
                  # so we simply don't chain up.
              }
          },
      };



2)  I also need to be able to cache these attempts to change the
buffer and possibly duplicate the change in another buffer.  I'm not
sure how easy that would be but if anyone has any pointers, I'd
appriciate it.

in IRC you mentioned that this is going to involve communicating with other applications, so it's really a question of interprocess communication protocols rather than how to implement it in a GtkTextBuffer. basically, you'd intercept the calls on the buffer and re-route them to the server; then you'd read all of your changes from the server. in effect, the view would never actually change the buffer.


3) Lastly I need to add my own code into the main Gtk loop.  This
should be really easy but I can't figure it out.

depends on what you want to do.

if you want to have code that fires every so many milliseconds, use a timeout -- Glib::Timeout->add ($msec, $callback);

if you want to monitor a file handle (e.g. socket) for asynchronous input, then use an IO watch -- Glib::IO->add_watch(fileno SOCKET, $condition, $callback).

if you want to defer an operation until some short time later, then use a single-shot idle -- Glib::Idle->add ($callback), where $callback returns FALSE. this will be run the next time the event loop runs out of things to process. repeating idles can bog down your system, so be sparing with them.

--
He's so good, you're gonna rock, and if you don't rock, it's your own fault.
  -- kk, describing the perks of having a very good drummer.




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