from gi.repository import Gtk
from gi.repository import GObject


class ListModel(GObject.GObject, Gtk.TreeModel):
    __gsignals__ = {
        'ready': (GObject.SignalFlags.RUN_FIRST, None, ([])),
        'progress': (GObject.SignalFlags.RUN_FIRST, None, ([])),
    }

    YEAR = 0
    FILM = 1
    DIRECTOR = 2

    _COLUMN_TYPES = {
        YEAR: int,
        FILM: str,
        DIRECTOR: str,
        }

    def __init__(self):
        GObject.GObject.__init__(self)

        self._result_set = [
            [1983, 'E La Nave Va', 'Fellini'],
            [1975, 'The Mirror', 'Tarkovskiy'],
            [2003, 'Kill Bill', 'Tarantino'],
            ]

    def set_ready(self):
        self.emit('ready')

    def do_get_n_columns(self):
        return len(ListModel._COLUMN_TYPES)

    def do_get_column_type(self, index):
        return ListModel._COLUMN_TYPES[index]

    def do_iter_n_children(self, iterator):
        if iterator == None:
            return len(self._result_set)
        else:
            return 0

    def do_get_value(self, iterator, column):
        idx = iterator.user_data

        if column == self.DIRECTOR:
            director = self._result_set[idx][column]
            return len(director), director
        else:
            return self._result_set[idx][column]

    def do_iter_nth_child(self, parent_iter, n):
        return (False, None)

    def do_get_path(self, iterator):
        idx = iterator.user_data
        treepath = Gtk.TreePath((idx,))
        return treepath

    def do_get_iter(self, path):
        idx = path.get_indices()[0]
        iterator = Gtk.TreeIter()
        iterator.user_data = idx
        return (True, iterator)

    def do_iter_next(self, iterator):
        idx = iterator.user_data + 1
        if idx >= len(self._result_set):
            iterator.stamp = -1
            return (False, iterator)
        else:
            iterator.user_data = idx
            return (True, iterator)

    def do_get_flags(self):
        return Gtk.TreeModelFlags.ITERS_PERSIST | Gtk.TreeModelFlags.LIST_ONLY

    def do_iter_children(self, iterator):
        return (False, iterator)

    def do_iter_has_child(self, iterator):
        return False

    def do_iter_parent(self, iterator):
        return (False, Gtk.TreeIter())


model = ListModel()
row = model[0]

# calling row[column_index] returns only the first element:
print(row[ListModel.DIRECTOR])

# internally calls model get_value, so this is the same as above:
print(model.get_value(row.iter, ListModel.DIRECTOR))

# calling model do_get_value directly works fine:
print(model.do_get_value(row.iter, ListModel.DIRECTOR))
