#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2005  Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

# $Id: PeopleStore.py,v 1.14.2.2 2005/01/24 18:50:00 rshura Exp $
 
#-------------------------------------------------------------------------
#
# GNOME
#
#-------------------------------------------------------------------------
from gobject import TYPE_STRING, TYPE_INT
import gtk
import pango

#-------------------------------------------------------------------------
#
# internationalization
#
#-------------------------------------------------------------------------
from gettext import gettext as _

#-------------------------------------------------------------------------
#
# constants
#
#-------------------------------------------------------------------------
_BCOL = 8
_IDCOL = 1

_TOP_FONT=pango.WEIGHT_ULTRABOLD
_TEXT_FONT=pango.WEIGHT_NORMAL

#-------------------------------------------------------------------------
#
# PeopleStore
#
#-------------------------------------------------------------------------
class PeopleStore:
    def __init__(self,tree,parent,select_func=None,event_func=None,
                 mode=gtk.SELECTION_SINGLE):

        self.titles  = [
            (_('Name'),5,250), (_('ID'),1,50),(_('Gender'),2,70),
            (_('Birth date'),6,150),(_('Death date'),7,150)
            ]

        ncols = len(self.titles) + 3
        self.tree = tree
        self.parent = parent
        self.tree.connect('row-expanded',self.on_row_expanded)
        self.mylist = [TYPE_STRING]*ncols + [TYPE_INT]

        self.tree.set_rules_hint(gtk.TRUE)
        self.model = None
        self.tree_roots = {}
        self.tree_open = {}
        self.tree_list = {}
        self.selection = None
        self.mode = mode
        self.new_model()
        self.count = 0
        self.cid = None
        self.cids = []
        
        cnum = 0
        for name in self.titles:
            renderer = gtk.CellRendererText()
            renderer.set_fixed_height_from_font(1)
            if name[0] != '':
                column = gtk.TreeViewColumn(name[0],renderer,text=cnum)
                column.set_min_width(name[2])
                column.set_resizable(gtk.TRUE)
                column.set_clickable(gtk.TRUE)
                column.set_sort_column_id(name[1])

                cnum +=  1
                self.cids.append(name[1])
                self.tree.append_column(column)
                
        self.connect_model()
        
        if select_func:
            self.selection.connect('changed',select_func)
        if event_func:
            self.double_click = event_func
            self.tree.connect('row_activated', self.row_activated)

    def row_activated (self, treeview, path, column):
        self.double_click (treeview)

    def enable_sort(self):
        if self.cids[0] != -1:
            self.model.set_sort_column_id(self.cids[0],gtk.SORT_ASCENDING)

    def unselect(self):
        self.selection.unselect_all()

    def set_reorderable(self,order):
        self.tree.set_reorderable(order)
        
    def new_model(self):
        if self.model:
            self.cid = self.model.get_sort_column_id()
            del self.model
            del self.selection
        self.count = 0

        self.model = gtk.TreeStore(*self.mylist)
        self.selection = self.tree.get_selection()
        self.selection.set_mode(self.mode)
        self.sel_iter = None
        
    def connect_model(self):
        self.tree.set_model(self.model)
        if self.sel_iter:
            self.selection.select_iter(self.sel_iter)
        if self.cid:
            self.model.set_sort_column_id(self.cid[0],self.cid[1])
        self.sort()

    def sort(self):
        val = self.model.get_sort_column_id()
        col = val[0]
        if col < 0:
            return
        if col > 0:
            self.model.set_sort_column_id(col,val[1])
        else:
            self.model.set_sort_column_id(self.cids[0],val[1])
        self.model.sort_column_changed()
        
    def get_selected(self):
        return self.selection.get_selected()

    def get_row_at(self,x,y):
        path = self.tree.get_path_at_pos(x,y)
        if path == None:
            return self.count -1
        else:
            return path[0][0]-1

    def get_selected_row(self):
        store, iter = self.selection.get_selected()
        if iter:
            rows = store.get_path(iter)
            return rows[0]
        else:
            return -1

    def get_selected_objects(self):
        if self.count == 0:
            return []
        elif self.mode == gtk.SELECTION_SINGLE:
            store,iter = self.selection.get_selected()
            if iter:
                return [self.model.get_value(iter,_IDCOL)]
            else:
                return []
        else:
            mlist = []
            self.selection.selected_foreach(self.blist,mlist)
            return mlist

    def get_icon(self):
        if self.mode == gtk.SELECTION_SINGLE:
            store,iter = self.selection.get_selected()
            path = self.model.get_path(iter)
        else:
            mlist = []
            self.selection.selected_foreach(self.blist,mlist)
            path = self.model.get_path(mlist[0])
        return self.tree.create_row_drag_icon(path)

    def blist(self,store,path,iter,id_list):
        id_list.append(self.model.get_value(iter,_IDCOL))

    def clear(self):
        self.count = 0
        self.tree_roots = {}
        self.tree_open = {}
        self.model.clear()

    def remove(self,iter):
        try:
            iter_parent = self.model.iter_parent (iter)
            self.model.remove(iter)
            if iter_parent and not self.model.iter_has_child (iter_parent):
                name = unicode(self.model.get_value(iter_parent,0))
                self.model.remove (iter_parent)
                if self.tree_roots.has_key(name):
                    del self.tree_roots[name]
                if self.tree_open.has_key(name):
                    del self.tree_open[name]
                if self.tree_list.has_key(name):
                    del self.tree_list[name]
            self.count = self.count - 1
        except:
            pass
        
    def get_row(self,iter):
        row = self.model.get_path(iter)
        return row[0]

    def select_row(self,row):
        self.selection.select_path((row))

    def select_iter(self,iter):
        self.selection.select_iter(iter)
    
    def get_object(self,iter):
        return self.model.get_value(iter,_IDCOL)
        
    def insert(self,position,data,info=None,select=0):
        self.count = self.count + 1
        iter = self.model.insert(position)
        col = 0
        for object in data:
            self.model.set_value(iter,col,object)
            col = col + 1
        self.model.set_value(iter,_IDCOL,info)
        self.model.set_value(iter,_BCOL,_TOP_FONT)
        if select:
            self.selection.select_iter(iter)
        return iter
    
    def get_data(self,iter,cols):
        return [ self.model.get_value(iter,c) for c in cols ]

    def on_row_expanded(self, view, iter, path):
        name = self.model.get_value(iter,0)
        self.fill_row(name,iter)

    def expand_row(self,name,iter=None):
        path = self.model.get_path(self.tree_roots[unicode(name)])
        self.parent.parent.status_text(_('Updating display...'))
        self.tree.expand_row(path,1)
        self.parent.parent.modify_statusbar()

    def fill_row(self,name,iter=None):
        name = unicode(name)
        
        if not iter:
            iter = self.tree_roots[name]
        child = self.model.iter_children(iter)

        if self.model.get_value(child,0) is None:
            self.model.remove(child)
            for d in self.tree_list[name]:
                new_iter = self.model.append(iter)
                self.model.set(new_iter,0,d[0],1,d[1],2,d[2],3,d[3],4,d[4],
                               5,d[5],6,d[6],7,d[7])
                self.parent.id2col[d[1]] = (self,new_iter)
        self.expand_row (name, iter)

    def add(self,data,select=0):
        self.count = self.count + 1

        name = unicode(data[-1])
        if self.tree_roots.has_key(name):
            top = self.tree_roots[name]
        else:
            top = self.model.append(None)
            self.model.append(top)
            self.tree_open[name] = 0
            self.tree_list[name] = []
            self.model.set_value(top,0,name)
            self.model.set_value(top,5,name.upper())
            self.model.set_value(top,_BCOL,_TOP_FONT)
            self.tree_roots[name] = top

        if self.tree_open[name] or select:
            iter = self.model.append(top)
            col = 0
            for object in data[:-1]:
                self.model.set_value(iter,col,object)
                col = col + 1
            self.model.set_value(iter,_BCOL,_TEXT_FONT)
            if select:
                self.sel_iter = iter
                self.selection.select_iter(self.sel_iter)
            return iter
        else:
            self.tree_list[name].append(data)
            return None

    def set(self,iter,data,select=0):
        col = 0
        for object in data:
            self.model.set_value(iter,col,object)
            col = col + 1
        self.model.set_value(iter,_BCOL,_TEXT_FONT)
        if select:
            self.sel_iter = iter
        return iter

    def add_and_select(self,data):
        self.count = self.count + 1
        iter = self.model.append()
        col = 0
        for object in data:
            self.model.set_value(iter,col,object)
            col = col + 1
        self.model.set_value(iter,_BCOL,_TEXT_FONT)
        self.selection.select_iter(iter)

    def center_selected(self):
        model,iter = self.selection.get_selected()
        if iter:
            path = model.get_path(iter)
            self.tree.scroll_to_cell(path,None,gtk.TRUE,0.5,0.5)
