コード例 #1
0
ファイル: diagrampage.py プロジェクト: otomazeli/gaphor
    def set_drawing_style(self, sloppiness=0.0):
        """Set the drawing style for the diagram. 0.0 is straight,
        2.0 is very sloppy.  If the sloppiness is set to be anything
        greater than 0.0, the FreeHandPainter instances will be used
        for both the item painter and the box painter.  Otherwise, by
        default, the ItemPainter is used for the item and
        BoundingBoxPainter for the box."""

        view = self.view

        if sloppiness:

            item_painter = FreeHandPainter(ItemPainter(), sloppiness=sloppiness)
            box_painter = FreeHandPainter(BoundingBoxPainter(), sloppiness=sloppiness)

        else:

            item_painter = ItemPainter()
            box_painter = BoundingBoxPainter()

        view.painter = (
            PainterChain()
            .append(item_painter)
            .append(HandlePainter())
            .append(FocusedItemPainter())
            .append(ToolPainter())
        )

        view.bounding_box_painter = box_painter

        view.queue_draw_refresh()
コード例 #2
0
    def set_drawing_style(self):
        """Set the drawing style for the diagram based on the active style
        sheet."""
        assert self.view
        assert self.diagram_css

        style = self.diagram.style(StyledDiagram(self.diagram, self.view))

        bg = style.get("background-color")
        self.diagram_css.load_from_data(
            f"diagramview {{ background-color: rgba({int(255*bg[0])}, {int(255*bg[1])}, {int(255*bg[2])}, {bg[3]}) }}"
            .encode() if bg else "".encode())

        sloppiness = style.get("line-style", 0.0)

        item_painter = ItemPainter()

        view = self.view

        if sloppiness:
            item_painter = FreeHandPainter(ItemPainter(),
                                           sloppiness=sloppiness)

        view.painter = (PainterChain().append(item_painter).append(
            HandlePainter()).append(FocusedItemPainter()).append(
                ToolPainter()))
        view.bounding_box_painter = BoundingBoxPainter(item_painter)

        view.queue_draw_refresh()
コード例 #3
0
def view(diagram):
    view = GtkView(model=diagram, selection=Selection())
    view._qtree.resize((-100, -100, 400, 400))
    item_painter = ItemPainter(view.selection)
    view.painter = item_painter
    view.bounding_box_painter = BoundingBoxPainter(item_painter)
    return view
コード例 #4
0
    def update_painters(self, view, diagram):
        style = diagram.style(StyledDiagram(diagram))

        sloppiness = style.get("line-style", 0.0)

        if sloppiness:
            view.painter = FreeHandPainter(ItemPainter(), sloppiness)
        else:
            view.painter = ItemPainter()
        view.bounding_box_painter = BoundingBoxPainter(view.painter)
コード例 #5
0
ファイル: __init__.py プロジェクト: seryafarma/gaphor
    def update_painters(self, view):
        sloppiness = self.properties.get("diagram.sloppiness", 0)

        if sloppiness:
            view.painter = FreeHandPainter(ItemPainter(), sloppiness)
            view.bounding_box_painter = FreeHandPainter(
                BoundingBoxPainter(), sloppiness
            )
        else:
            view.painter = ItemPainter()
コード例 #6
0
ファイル: conftest.py プロジェクト: milotype/gaphor
    def __init__(self):
        self.session = Session(services=self.services)
        self.element_factory = self.session.get_service("element_factory")
        self.modeling_language = self.session.get_service("modeling_language")
        assert len(list(self.element_factory.select())) == 0, list(
            self.element_factory.select())
        self.diagram = self.element_factory.create(UML.Diagram)

        # We need to hook up a view for now, so updates are done instantly
        self.view = GtkView(self.diagram, selection=Selection())
        self.view.painter = ItemPainter(self.view.selection)
        self.view.bounding_box_painter = BoundingBoxPainter(self.view.painter)
        assert len(list(self.element_factory.select())) == 1, list(
            self.element_factory.select())
コード例 #7
0
 def update_painters(self, view):
     
     self.logger.info('Updating painters')
     self.logger.debug('View is %s' % view)
     
     sloppiness = self.properties('diagram.sloppiness', 0)
     
     self.logger.debug('Sloppiness is %s' % sloppiness)
     
     if sloppiness:
         view.painter = FreeHandPainter(ItemPainter(), sloppiness)
         view.bounding_box_painter = FreeHandPainter(BoundingBoxPainter(), sloppiness)
     else:
         view.painter = ItemPainter()
コード例 #8
0
    def update_painters(self, view):

        logger.info("Updating painters")
        logger.debug("View is %s" % view)

        sloppiness = self.properties("diagram.sloppiness", 0)

        logger.debug("Sloppiness is %s" % sloppiness)

        if sloppiness:
            view.painter = FreeHandPainter(ItemPainter(), sloppiness)
            view.bounding_box_painter = FreeHandPainter(
                BoundingBoxPainter(), sloppiness)
        else:
            view.painter = ItemPainter()
コード例 #9
0
    def __init__(self, canvas=None):
        self._matrix = cairo.Matrix()
        self._painter = DefaultPainter(self)
        self._bounding_box_painter = BoundingBoxPainter(self)

        # Handling selections.
        # TODO: Move this to a context?
        self._selected_items = set()
        self._focused_item = None
        self._hovered_item = None
        self._dropzone_item = None

        self._qtree = Quadtree()
        self._bounds = Rectangle(0, 0, 0, 0)

        self._canvas = None
        if canvas:
            self._set_canvas(canvas)
コード例 #10
0
    def on_write_demo_svg_clicked(button):
        assert view.model
        painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        bounding_box = BoundingBoxPainter(painter).bounding_box(
            canvas.get_all_items(), tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        surface = cairo.SVGSurface("demo.svg", int(bounding_box.width),
                                   int(bounding_box.height))
        cr = cairo.Context(surface)
        cr.translate(-bounding_box.x, -bounding_box.y)
        painter.paint(items=list(view.model.get_all_items()), cairo=cr)
        cr.show_page()
        surface.flush()
        surface.finish()
コード例 #11
0
    def render(self, diagram, new_surface):
        diagram.update_now(diagram.get_all_items())

        painter = new_painter(diagram)

        # Update bounding boxes with a temporary CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        bounding_box = BoundingBoxPainter(painter).bounding_box(
            diagram.get_all_items(), tmpcr
        )
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = bounding_box.width, bounding_box.height
        surface = new_surface(w, h)
        cr = cairo.Context(surface)
        cr.translate(-bounding_box.x, -bounding_box.y)
        painter.paint(items=diagram.get_all_items(), cairo=cr)
        cr.show_page()
        return surface
コード例 #12
0
def create_window(canvas, title, zoom=1.0):
    view = GtkView()
    view.painter = (
        PainterChain()
        .append(FreeHandPainter(ItemPainter()))
        .append(HandlePainter())
        .append(FocusedItemPainter())
        .append(ToolPainter())
    )
    view.bounding_box_painter = FreeHandPainter(BoundingBoxPainter(ItemPainter()))
    w = Gtk.Window()
    w.set_title(title)
    w.set_default_size(400, 120)
    h = Gtk.HBox()
    w.add(h)

    # VBox contains buttons that can be used to manipulate the canvas:
    v = Gtk.VBox()
    v.set_property("border-width", 3)
    v.set_property("spacing", 2)
    f = Gtk.Frame()
    f.set_property("border-width", 1)
    f.add(v)
    h.pack_start(f, False, True, 0)

    v.add(Gtk.Label.new("Item placement:"))

    b = Gtk.Button.new_with_label("Add box")

    def on_clicked(button, view):
        # view.window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.CROSSHAIR))
        view.tool.grab(PlacementTool(view, factory(view, MyBox), HandleTool(), 2))

    b.connect("clicked", on_clicked, view)
    v.add(b)

    b = Gtk.Button.new_with_label("Add line")

    def on_clicked(button):
        view.tool.grab(PlacementTool(view, factory(view, MyLine), HandleTool(), 1))

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Zooming:"))

    b = Gtk.Button.new_with_label("Zoom in")

    def on_clicked(button):
        view.zoom(1.2)

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Zoom out")

    def on_clicked(button):
        view.zoom(1 / 1.2)

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Misc:"))

    b = Gtk.Button.new_with_label("Split line")

    def on_clicked(button):
        if isinstance(view.focused_item, Line):
            segment = Segment(view.focused_item, view)
            segment.split_segment(0)
            view.queue_draw_item(view.focused_item)

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Delete focused")

    def on_clicked(button):
        if view.focused_item:
            canvas.remove(view.focused_item)

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("State:"))
    b = Gtk.ToggleButton.new_with_label("Record")

    def on_toggled(button):
        global undo_list
        if button.get_active():
            print("start recording")
            del undo_list[:]
            state.subscribers.add(undo_handler)
        else:
            print("stop recording")
            state.subscribers.remove(undo_handler)

    b.connect("toggled", on_toggled)
    v.add(b)

    b = Gtk.Button.new_with_label("Play back")

    def on_clicked(self):
        global undo_list
        apply_me = list(undo_list)
        del undo_list[:]
        print("Actions on the undo stack:", len(apply_me))
        apply_me.reverse()
        saveapply = state.saveapply
        for event in apply_me:
            print("Undo: invoking", event)
            saveapply(*event)
            print("New undo stack size:", len(undo_list))
            # Visualize each event:
            # while Gtk.events_pending():
            #    Gtk.main_iteration()

    b.connect("clicked", on_clicked)
    v.add(b)

    v.add(Gtk.Label.new("Export:"))

    b = Gtk.Button.new_with_label("Write demo.png")

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporary CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h))
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
        cr.save()
        svgview.paint(cr)

        cr.restore()
        cr.show_page()
        surface.write_to_png("demo.png")

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Write demo.svg")

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.SVGSurface("demo.svg", w, h)
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x, -svgview.bounding_box.y)
        svgview.paint(cr)
        cr.show_page()
        surface.flush()
        surface.finish()

    b.connect("clicked", on_clicked)
    v.add(b)

    b = Gtk.Button.new_with_label("Dump QTree")

    def on_clicked(button, li):
        view._qtree.dump()

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Pickle (save)")

    def on_clicked(button, li):
        f = open("demo.pickled", "wb")
        try:
            import pickle

            pickle.dump(view.canvas, f)
        finally:
            f.close()

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Unpickle (load)")

    def on_clicked(button, li):
        f = open("demo.pickled", "rb")
        try:
            import pickle

            canvas = pickle.load(f)
            canvas.update_now()
        finally:
            f.close()
        create_window(canvas, "Unpickled diagram")

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Unpickle (in place)")

    def on_clicked(button, li):
        f = open("demo.pickled", "rb")
        try:
            import pickle

            canvas = pickle.load(f)
        finally:
            f.close()
        # [i.request_update() for i in canvas.get_all_items()]
        canvas.update_now()
        view.canvas = canvas

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    b = Gtk.Button.new_with_label("Reattach (in place)")

    def on_clicked(button, li):
        view.canvas = None
        view.canvas = canvas

    b.connect("clicked", on_clicked, [0])
    v.add(b)

    # Add the actual View:

    view.canvas = canvas
    view.zoom(zoom)
    view.set_size_request(150, 120)
    s = Gtk.ScrolledWindow.new()
    s.set_hexpand(True)
    s.add(view)
    h.add(s)

    w.show_all()

    w.connect("destroy", Gtk.main_quit)

    def handle_changed(view, item, what):
        print(what, "changed: ", item)

    view.connect("focus-changed", handle_changed, "focus")
    view.connect("hover-changed", handle_changed, "hover")
    view.connect("selection-changed", handle_changed, "selection")
コード例 #13
0
ファイル: gaphorconvert.py プロジェクト: seryafarma/gaphor
def main(argv=sys.argv[1:]):
    def message(msg):
        """
        Print message if user set verbose mode.
        """
        if options.verbose:
            print(msg, file=sys.stderr)

    usage = "usage: %prog [options] file1 file2..."

    parser = optparse.OptionParser(usage=usage)

    parser.add_option("-v",
                      "--verbose",
                      dest="verbose",
                      action="store_true",
                      help="verbose output")
    parser.add_option(
        "-u",
        "--use-underscores",
        dest="underscores",
        action="store_true",
        help="use underscores instead of spaces for output filenames",
    )
    parser.add_option("-d",
                      "--dir",
                      dest="dir",
                      metavar="directory",
                      help="output to directory")
    parser.add_option(
        "-f",
        "--format",
        dest="format",
        metavar="format",
        help="output file format, default pdf",
        default="pdf",
        choices=["pdf", "svg", "png"],
    )
    parser.add_option(
        "-r",
        "--regex",
        dest="regex",
        metavar="regex",
        help="process diagrams which name matches given regular expression;"
        " name includes package name; regular expressions are case insensitive",
    )

    (options, args) = parser.parse_args(argv)

    if not args:
        parser.print_help()

    session = Session(services=[
        "event_manager",
        "component_registry",
        "element_factory",
        "element_dispatcher",
        "modeling_language",
    ])
    factory = session.get_service("element_factory")
    modeling_language = session.get_service("modeling_language")

    name_re = None
    if options.regex:
        name_re = re.compile(options.regex, re.I)

    # we should have some gaphor files to be processed at this point
    for model in args:
        message(f"loading model {model}")
        storage.load(model, factory, modeling_language)
        message("ready for rendering")

        for diagram in factory.select(Diagram):
            odir = pkg2dir(diagram.package)

            # just diagram name
            dname = diagram.name
            # full diagram name including package path
            pname = f"{odir}/{dname}"

            if options.underscores:
                odir = odir.replace(" ", "_")
                dname = dname.replace(" ", "_")

            if name_re and not name_re.search(pname):
                message(f"skipping {pname}")
                continue

            if options.dir:
                odir = f"{options.dir}/{odir}"

            outfilename = f"{odir}/{dname}.{options.format}"

            if not os.path.exists(odir):
                message(f"creating dir {odir}")
                os.makedirs(odir)

            message(f"rendering: {pname} -> {outfilename}...")

            view = View(diagram.canvas)
            view.painter = ItemPainter()
            view.bounding_box_painter = BoundingBoxPainter()

            tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
            tmpcr = cairo.Context(tmpsurface)
            view.update_bounding_box(tmpcr)
            tmpcr.show_page()
            tmpsurface.flush()

            w, h = view.bounding_box.width, view.bounding_box.height
            if options.format == "pdf":
                surface = cairo.PDFSurface(outfilename, w, h)
            elif options.format == "svg":
                surface = cairo.SVGSurface(outfilename, w, h)
            elif options.format == "png":
                surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w + 1),
                                             int(h + 1))
            else:
                assert False, f"unknown format {options.format}"
            cr = cairo.Context(surface)
            view.matrix.translate(-view.bounding_box.x, -view.bounding_box.y)
            paint(view, cr)
            cr.show_page()

            if options.format == "png":
                surface.write_to_png(outfilename)

            surface.flush()
            surface.finish()
コード例 #14
0
ファイル: demo.py プロジェクト: sebastian-brunner/gaphas
def create_window(canvas, title, zoom=1.0):
    view = GtkView()
    view.painter = PainterChain(). \
        append(FreeHandPainter(ItemPainter())). \
        append(HandlePainter()). \
        append(FocusedItemPainter()). \
        append(ToolPainter())
    view.bounding_box_painter = FreeHandPainter(BoundingBoxPainter())
    w = gtk.Window()
    w.set_title(title)
    h = gtk.HBox()
    w.add(h)

    # VBox contains buttons that can be used to manipulate the canvas:
    v = gtk.VBox()
    v.set_property('border-width', 3)
    v.set_property('spacing', 2)
    f = gtk.Frame()
    f.set_property('border-width', 1)
    f.add(v)
    h.pack_start(f, expand=False)

    v.add(gtk.Label('Item placement:'))

    b = gtk.Button('Add box')

    def on_clicked(button, view):
        #view.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.CROSSHAIR))
        view.tool.grab(
            PlacementTool(view, factory(view, MyBox), HandleTool(), 2))

    b.connect('clicked', on_clicked, view)
    v.add(b)

    b = gtk.Button('Add line')

    def on_clicked(button):
        view.tool.grab(
            PlacementTool(view, factory(view, MyLine), HandleTool(), 1))

    b.connect('clicked', on_clicked)
    v.add(b)

    v.add(gtk.Label('Zooming:'))

    b = gtk.Button('Zoom in')

    def on_clicked(button):
        view.zoom(1.2)

    b.connect('clicked', on_clicked)
    v.add(b)

    b = gtk.Button('Zoom out')

    def on_clicked(button):
        view.zoom(1 / 1.2)

    b.connect('clicked', on_clicked)
    v.add(b)

    v.add(gtk.Label('Misc:'))

    b = gtk.Button('Split line')

    def on_clicked(button):
        if isinstance(view.focused_item, Line):
            segment = Segment(view.focused_item, view)
            segment.split_segment(0)
            view.queue_draw_item(view.focused_item)

    b.connect('clicked', on_clicked)
    v.add(b)

    b = gtk.Button('Delete focused')

    def on_clicked(button):
        if view.focused_item:
            canvas.remove(view.focused_item)
            #print 'items:', canvas.get_all_items()

    b.connect('clicked', on_clicked)
    v.add(b)

    v.add(gtk.Label('State:'))
    b = gtk.ToggleButton('Record')

    def on_toggled(button):
        global undo_list
        if button.get_active():
            print 'start recording'
            del undo_list[:]
            state.subscribers.add(undo_handler)
        else:
            print 'stop recording'
            state.subscribers.remove(undo_handler)

    b.connect('toggled', on_toggled)
    v.add(b)

    b = gtk.Button('Play back')

    def on_clicked(self):
        global undo_list
        apply_me = list(undo_list)
        del undo_list[:]
        print 'Actions on the undo stack:', len(apply_me)
        apply_me.reverse()
        saveapply = state.saveapply
        for event in apply_me:
            print 'Undo: invoking', event
            saveapply(*event)
            print 'New undo stack size:', len(undo_list)
            # Visualize each event:
            #while gtk.events_pending():
            #    gtk.main_iteration()

    b.connect('clicked', on_clicked)
    v.add(b)

    v.add(gtk.Label('Export:'))

    b = gtk.Button('Write demo.png')

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(w), int(h))
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x,
                                 -svgview.bounding_box.y)
        cr.save()
        svgview.paint(cr)

        cr.restore()
        cr.show_page()
        surface.write_to_png('demo.png')

    b.connect('clicked', on_clicked)
    v.add(b)

    b = gtk.Button('Write demo.svg')

    def on_clicked(button):
        svgview = View(view.canvas)
        svgview.painter = ItemPainter()

        # Update bounding boxes with a temporaly CairoContext
        # (used for stuff like calculating font metrics)
        tmpsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 0, 0)
        tmpcr = cairo.Context(tmpsurface)
        svgview.update_bounding_box(tmpcr)
        tmpcr.show_page()
        tmpsurface.flush()

        w, h = svgview.bounding_box.width, svgview.bounding_box.height
        surface = cairo.SVGSurface('demo.svg', w, h)
        cr = cairo.Context(surface)
        svgview.matrix.translate(-svgview.bounding_box.x,
                                 -svgview.bounding_box.y)
        svgview.paint(cr)
        cr.show_page()
        surface.flush()
        surface.finish()

    b.connect('clicked', on_clicked)
    v.add(b)

    b = gtk.Button('Dump QTree')

    def on_clicked(button, li):
        view._qtree.dump()

    b.connect('clicked', on_clicked, [0])
    v.add(b)

    b = gtk.Button('Pickle (save)')

    def on_clicked(button, li):
        f = open('demo.pickled', 'w')
        try:
            import cPickle as pickle
            pickle.dump(view.canvas, f)
        finally:
            f.close()

    b.connect('clicked', on_clicked, [0])
    v.add(b)

    b = gtk.Button('Unpickle (load)')

    def on_clicked(button, li):
        f = open('demo.pickled', 'r')
        try:
            import cPickle as pickle
            canvas = pickle.load(f)
            canvas.update_now()
        finally:
            f.close()
        create_window(canvas, 'Unpickled diagram')

    b.connect('clicked', on_clicked, [0])
    v.add(b)

    b = gtk.Button('Unpickle (in place)')

    def on_clicked(button, li):
        f = open('demo.pickled', 'r')
        try:
            import cPickle as pickle
            canvas = pickle.load(f)
        finally:
            f.close()
        #[i.request_update() for i in canvas.get_all_items()]
        canvas.update_now()
        view.canvas = canvas

    b.connect('clicked', on_clicked, [0])
    v.add(b)

    b = gtk.Button('Reattach (in place)')

    def on_clicked(button, li):
        view.canvas = None
        view.canvas = canvas

    b.connect('clicked', on_clicked, [0])
    v.add(b)

    # Add the actual View:

    view.canvas = canvas
    view.zoom(zoom)
    view.set_size_request(150, 120)
    s = gtk.ScrolledWindow()
    s.add(view)
    h.add(s)

    w.show_all()

    w.connect('destroy', gtk.main_quit)

    def handle_changed(view, item, what):
        print what, 'changed: ', item

    view.connect('focus-changed', handle_changed, 'focus')
    view.connect('hover-changed', handle_changed, 'hover')
    view.connect('selection-changed', handle_changed, 'selection')