Logo Search packages:      
Sourcecode: iceme version File versions  Download package

DndCTree.py

import sys
from gtk import *

class DndCTree(GtkCTree):

    COLUMN_TITLES_HEIGHT = 24

    def __init__(self, cols=1, tree_col=0, titles=None, _obj=None):
        GtkCTree.__init__(self, cols, tree_col, titles, _obj)
        GtkCTree.set_selection_mode(self, SELECTION_BROWSE)
        self.column_titles_height = self.COLUMN_TITLES_HEIGHT
        targets = [('application/x-GtkCTreeNode',
                    TARGET_SAME_APP|TARGET_SAME_WIDGET, -1)]
        self.drag_source_set(GDK.BUTTON1_MASK, targets, GDK.ACTION_MOVE)
        self.drag_dest_set(DEST_DEFAULT_ALL, targets, GDK.ACTION_MOVE)

        self.connect("drag-begin", self.cb_drag_begin)
        self.connect("drag-motion", self.cb_drag_motion)
        self.connect("drag-data-get", self.cb_drag_data_get)
        self.connect("drag-data-received", self.cb_drag_data_received)
        self.connect("drag-end", self.cb_drag_end)

    def cb_drag_data_get(self, widget, context, data, info, time):
        data.set(data.target, 1, "dummy-data")

    def cb_drag_begin(self, widget, context):
        if self.selection:
            self.the_drag_node = self.selection[0]

    def cb_drag_motion(self, widget, context, x, y, time):
        selected = self.get_selection_info(x, y - self.column_titles_height)
        if selected:
            row = selected[0]
            self.select_row(row, 0)
            visibility = self.row_is_visible(row)
            if visibility != VISIBILITY_FULL:
                visibility_next = self.row_is_visible(row + 1)
                if visibility_next == VISIBILITY_NONE:
                    self.moveto(row, 0, 1.0, 0.0)
                else:
                    self.moveto(row, 0, 0.0, 0.0)

    def cb_drag_data_received(self, widget, context, x, y, data, info, time):
        selected = self.get_selection_info(x, y - self.column_titles_height)
        if selected:
            target_node = self.node_nth(selected[0])
            # move self.the_drag_node under target_node
            if target_node == self.the_drag_node:
                # source = target: no move neccessary
                self.drag_finish(context, FALSE, TRUE, time)
                return
            if self.find(self.the_drag_node, target_node):
                # source is an ancestor of target: move not allowed
                self.drag_finish(context, FALSE, TRUE, time)
            if target_node.is_leaf:
                new_parent = target_node.parent
                new_sibling = target_node.sibling
            else:
                new_parent = target_node
                if target_node.children:
                    new_sibling = target_node.children[0]
                else:
                    new_sibling = None
            if new_sibling == self.the_drag_node:
                # move under direct predecessor: no move neccessary
                self.drag_finish(context, FALSE, TRUE, time)
                return
            if not self.move_is_permitted(self.the_drag_node,
                                          target_node,
                                          new_parent,
                                          new_sibling):
                self.drag_finish(context, FALSE, TRUE, time)
                return
            self.move(self.the_drag_node, new_parent, new_sibling)
            if not target_node.is_leaf:
                self.expand(target_node)
            self.drag_finish(context, TRUE, TRUE, time)

    def cb_drag_end(self, widget, context):
        self.the_drag_node = None

    def set_selection_mode(self, mode):
        if mode != SELECTION_BROWSE:
            sys.stderr.write("*** DndCTree.set_selection_mode:" \
                             " only supports SELECTION_BROWSE\n")

    def column_titles_show(self):
        GtkTree.column_titles_show(self)
        self.column_titles_height = self.COLUMN_TITLES_HEIGHT

    def column_titles_hide(self):
        GtkTree.column_titles_hide(self)
        self.column_titles_height = 0

    def move_is_permitted(self, source_node, target_node,
                          new_parent, new_sibling):
        """Tests, whether source_node may be moved under target_node,
        getting new_parent and new_sibling as its insert position.

        This is invoked after an drag gesture, before the actual move
        operation takes place. The default implementation always returns 1.
        Subclasses may override this to control the permissable drag
        operations.
        """
        return 1


DnDCTree = DndCTree



def test():
    tree = DndCTree(cols=2, titles=["Tree", "Type"] )
    tree.set_column_auto_resize(0, TRUE)
    n1  = tree.insert_node(None, None, ["n1" , "menu"]   , is_leaf=FALSE)
    n2  = tree.insert_node(n1,   None, ["n2" , "leaf"])
    n3  = tree.insert_node(n1,   None, ["n3" , "leaf"])
    n4  = tree.insert_node(None, None, ["n4" , "menu"]   , is_leaf=FALSE)
    n5  = tree.insert_node(None, None, ["n5" , "menu"]   , is_leaf=FALSE)
    n6  = tree.insert_node(None, None, ["n6" , "menu"]   , is_leaf=FALSE)
    n7  = tree.insert_node(n6,   None, ["n7" , "submenu"], is_leaf=FALSE)
    n8  = tree.insert_node(n7,   None, ["n8" , "submenu"], is_leaf=FALSE)
    n9  = tree.insert_node(n8,   None, ["n9" , "leaf"])
    n10 = tree.insert_node(None, None, ["n10", "leaf"])
    n11 = tree.insert_node(None, None, ["n11", "leaf"])
    n12 = tree.insert_node(None, None, ["n12", "leaf"])
    n13 = tree.insert_node(None, None, ["n13", "leaf"])
    tree.expand_recursive(n1)
    tree.expand_recursive(n6)
    tree.show()

    scrolled_win = GtkScrolledWindow()
    scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
    scrolled_win.add(tree)
    scrolled_win.show()

    window = GtkWindow()
    window.set_default_size(300, 300)
    window.connect("delete_event", mainquit)
    window.add(scrolled_win)
    window.show()

    mainloop()

if __name__ == "__main__":
    test()

Generated by  Doxygen 1.6.0   Back to index