21.3. Supplying the Selection
Prev | Chapter 21. Managing Selections | Next

## 21.3. Supplying the Selection

Supplying the selection is a bit more complicated. You must register handlers that will be called when your selection is requested. For each selection-target pair you will handle, you make a call to:

      widget.selection_add_target(selection, target, info)

`widget`, `selection`, and `target` identify the requests this handler will manage. When a request for a selection is received, the "selection_get" signal will be called. `info` is an integer that can be used as an enumerator to identify the specific target within the callback.

The callback has the signature:

      def selection_get(widget, selection_data, info, time):

The `gtk.SelectionData` is the same as above, but this time, we're responsible for filling in the fields `type`, `format` and `data`. (The `format` field is actually important here - the X server uses it to figure out whether the `data` needs to be byte-swapped or not. Usually it will be 8 - i.e. a character - or 32 - i.e. a integer.) This is done by calling the method:

      selection_data.set(type, format, data)

This PyGTK method can only handle string data so the `data` must be loaded into a Python string but `format` will be whatever the appropriate size is (e.g. 32 for atoms and integers, 8 for strings). The Python `struct` or `StringIO` modules can be used to convert non-string data to string data. For example, you can convert a list of integers to a string and set the `selection_data` by:

      ilist = [1, 2, 3, 4, 5]

      data = apply(struct.pack, ['%di'%len(ilist)] + ilist)

      selection_data.set("INTEGER", 32, data)

The following method sets the selection data from the given string:

      selection_data.set_text(str, len)

When prompted by the user, you claim ownership of the selection by calling:

      result = widget.selection_owner_set(selection, time=0L)

`result` will be `TRUE` if program successfully claimed the `selection`. If another application claims ownership of the `selection`, you will receive a "selection_clear_event".

As an example of supplying the selection, the setselection.py program adds selection functionality to a toggle button enclosed in a `gtk.EventBox`. (The `gtk.Eventbox` is needed because the selection must be associated with a `gtk.gdk.Window` and a `gtk.Button` is a "windowless" object in GTK+ 2.0.) When the toggle button is depressed, the program claims the primary selection. The only target supported (aside from certain targets like "TARGETS" supplied by GTK+ itself), is the "STRING" target. When this target is requested, a string representation of the time is returned. Figure 21.2, “Set Selection Example” illustrates the program display when the program has taken the primary selection ownership:

Figure 21.2. Set Selection Example

The setselection.py source code is:

        1	#!/usr/bin/env python
        2
        3	# example setselection.py
        4
        5	import pygtk
        6	pygtk.require('2.0')
        7	import gtk
        8	import time
        9
       10	class SetSelectionExample:
       11	    # Callback when the user toggles the selection
       12	    def selection_toggled(self, widget, window):
       13	        if widget.get_active():
       14	            self.have_selection = window.selection_owner_set("PRIMARY")
       15	            # if claiming the selection failed, we return the button to
       16	            # the out state
       17	            if not self.have_selection:
       18	                widget.set_active(False)
       19	        else:
       20	            if self.have_selection:
       21	                # Not possible to release the selection in PyGTK
       22	                # just mark that we don't have it
       23	                self.have_selection = False
       24	        return
       25
       26	    # Called when another application claims the selection
       27	    def selection_clear(self, widget, event):
       28	        self.have_selection = False
       29	        widget.set_active(False)
       30	        return True
       31
       32	    # Supplies the current time as the selection.
       33	    def selection_handle(self, widget, selection_data, info, time_stamp):
       34	        current_time = time.time()
       35	        timestr = time.asctime(time.localtime(current_time))
       36
       37	        # When we return a single string, it should not be null terminated.
       38	        # That will be done for us
       39	        selection_data.set_text(timestr, len(timestr))
       40	        return
       41
       42	    def __init__(self):
       43	        self.have_selection = False
       44	        # Create the toplevel window
       45	        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
       46	        window.set_title("Set Selection")
       47	        window.set_border_width(10)
       48	        window.connect("destroy", lambda w: gtk.main_quit())
       49	        self.window = window
       50	        # Create an eventbox to hold the button since it no longer has
       51	        # a GdkWindow
       52	        eventbox = gtk.EventBox()
       53	        eventbox.show()
       54	        window.add(eventbox)
       55
       56	        # Create a toggle button to act as the selection
       57	        selection_button = gtk.ToggleButton("Claim Selection")
       58	        eventbox.add(selection_button)
       59
       60	        selection_button.connect("toggled", self.selection_toggled, eventbox)
       61	        eventbox.connect_object("selection_clear_event", self.selection_clear,
       62	                                selection_button)
       63
       64	        eventbox.selection_add_target("PRIMARY", "STRING", 1)
       65	        eventbox.selection_add_target("PRIMARY", "COMPOUND_TEXT", 1)
       66	        eventbox.connect("selection_get", self.selection_handle)
       67	        selection_button.show()
       68	        window.show()
       69
       70	def main():
       71	    gtk.main()
       72	    return 0
       73
       74	if __name__ == "__main__":
       75	    SetSelectionExample()
       76	    main()

Prev | Up | Next
21.2. Retrieving the Selection | Home | Chapter 22. Drag-and-drop (DND)