3

I am trying to edit the same text (which I have stored in a GtkTextBuffer, but alternatives are welcome) with multiple cursors, each in a separate GtkTextView. I need all cursors to be able to edit the text (and be reflected in the other views). Moving one cursor (e.g., with the keyboard) should not move the other cursors.

For those familiar, I am trying to emulate the behaviour of emacs' split window.

What is the simplest way to do this?

Background

The Text Widget Overview states that

Each buffer can be displayed by any number of views.

except the cursor is stored in the GtkTextBuffer rather than the GtkTextView. In particular, moving the cursor in one view would change the cursor location in all other views.

More technical details

I'm actually using pygtk and gtksourceview2 in my specific example. In particular, the GtkTextView is a GtkSourceView (gtksourceview2.View in python). But my question is not pygtk specific.

foobar
  • 33
  • 2
  • Have you checked the samples in gtk-demo application ? There's one over there with multiples views for the same buffer, I tried to check the behavior you're relating but wasn't able. – erick2red Aug 11 '11 at 12:27
  • I have just checked the same sample in gtk-demo. I'm not sure what you mean by "I tried to check the behavior you're relating but wasn't able.". Do you mean that moving the cursor in one view does not move the cursor in the other? Note that the *scrollbars* in the other view does not move but the cursor does. If go to view2, move the cursor in view2 and the return to view1 using the left mouse button, the cursor is moved by the mouse click in view1. This is a fluke. Right click on view1 instead (followed by arrow keys) to see the behaviour I described. – foobar Aug 11 '11 at 13:25

1 Answers1

2

You can't do that with GtkSourceView out of the box - you'll have to write it yourself, unfortunately.

The way I would go about writing that, is to subclass GtkSourceBuffer. Make it 'wrap' the original GtkSourceBuffer, but maintain its own separate cursor position. Then create two of these 'wrapping' source buffers and put them in the source views.

Although, that wouldn't work if you wanted to have all the cursors displayed in all the source views. Maybe you could subclass GtkSourceBuffer and just have it maintain a separate cursor position for each view it's added to.

What would you do if you selected a different bit of text in each view? I'd think about it carefully before you start coding.

A quick'n'dirty way would be to connect to the 'focus-in-event' and 'focus-out-event' signals of the source views. On losing the focus, have the view record its current cursor position. Then on gaining the focus, have it restore that cursor position. That way, it would be almost like each view had its own cursor position.

ptomato
  • 56,175
  • 13
  • 112
  • 165
  • Thanks. That is rather unfortunate. But then I do not understand what is the intended use of multiple views with the same buffer. What is a simple example of an application needing this? I'd also still like to know what is the simplest (or at least one) way of writing is myself (while preserving the functionality of GtkSourceView as much as possible). – foobar Aug 11 '11 at 13:14
  • Well, I think there are no "simple" examples. I've written an application that does this, sf.net/projects/gnome-inform7, but if it were a simple application, it wouldn't need multiple views, I guess... – ptomato Aug 12 '11 at 00:10
  • I added some implementation ideas to my answer. – ptomato Aug 12 '11 at 00:13
  • Thanks, especially for the implementation details. I'm still designing the prototype for my project so the quick'n'dirty way might just work. (Emacs only has one selection mark with multiple cursors.) I said "simple example" to really mean a case I could understand without too much background (about the need for such a program). gnome-inform7 looks nice; I've only played IFs, but never written one. But what would be the advantage of, say, viewing the source in both views? (Not that you've claimed otherwise, but same behaviour occurs here if I selected the views with the right mouse button.) – foobar Aug 12 '11 at 13:52
  • @foobar, Do note that the cursor and the selection mark are the same in GTK. As for Inform 7, it isn't really meant to view the source in both views - it's just that you can view the source in whichever view you like while you're doing something else in the other view. – ptomato Aug 12 '11 at 20:08
  • I've implemented your quick'n'dirty way and it works well! I just added a TextMark to the source TextBuffer for each TextView and copy their (iter) locations on focus gain/loss. It seems TextBuffer initially has two TextMarks "insert" and "selection_bound". I could just create two TextMarks (instead of one) for each TextView if I also wanted to preserve the selection. As for gnome-inform7, this could be done if only one view is allowed per TextBuffer, by forcing views to be different. I wanted to know what is the intended use of multiple views with one buffer (when gtk was designed). – foobar Aug 12 '11 at 20:50