#  Copyright (C) 2004  Henning Jacobs <henning@srcco.de>
#
#  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.
#
#  $Id: ListViewWidget.py 82 2004-07-11 13:01:44Z henning $

from Tkinter import *
import Preferences
import broadcaster
import debug
import ToolTip
import vcard
import types

DEFAULT_FIELDS_SHOWN = [
    "FormattedName",
    "Organization",
    "Phone"]



class ListViewWidget(Frame):
    fields_shown = DEFAULT_FIELDS_SHOWN
    sortby = "SortName"
    def __init__(self, master, model, **kws):
        self.handles = []
        self.model = model
        self._dblclickcommand = kws.get("dblclickcommand", None)
        self._selectcommand = kws.get("selectcommand", None)
        Frame.__init__(self, master, class_="ListView")
        if Preferences.has_key('client.listview_columns'):
            self.fields_shown = Preferences.get('client.listview_columns', types.ListType)
        if Preferences.has_key('client.listview_sortby'):
            self.sortby = Preferences.get('client.listview_sortby')     
        self.__createWidgets()
        self.registerAtBroadcaster()
    def registerAtBroadcaster(self):
        broadcaster.Register(self.updateList,
            source='Contacts', title='Opened')
        broadcaster.Register(self.updateList,
            source='Contacts', title='Closed')
        broadcaster.Register(self.onContactDel,
            source='Contact', title='Deleted')
        broadcaster.Register(self.onContactNew,
            source='Contact', title='Added')
        broadcaster.Register(self.onContactSave,
            source='Contact', title='Saved')    
            
    def getUpdatedContactData(self):
        """Returns handle and fields_shown from the modified contact
        Call only from a broadcaster callback function"""
        handle = broadcaster.CurrentData()['handle']
        if broadcaster.CurrentTitle() != "Deleted":
            attrlist = self.model.QueryAttributes([handle],
                self.fields_shown)
            return (handle, attrlist[0]) 
        else:
            return (handle, None)
                
    def onContactNew(self):
        handle, attr = self.getUpdatedContactData()
        self.handles.append(handle)
        self.rows.append(attr)
        self.textlist.append(attr)
        idx = len(self.handles)-1
        srvidx = self.model.ListHandles(self.sortby).index(handle)
        if idx != srvidx:
            def move(list, x, y):
                temp = list[x]; del list[x]
                list.insert(y, temp)
            # and move our new Contact to it's sorted place:    
            move(self.handles, idx, srvidx)
            move(self.rows, idx, srvidx)
            self.textlist.remove(idx)
            self.textlist.insert(srvidx, attr)

        
    def onContactDel(self):
        handle, attr = self.getUpdatedContactData()
        idx = self.handles.index(handle)
        del self.handles[idx]
        del self.rows[idx]
        self.textlist.remove(idx)    
                
    def onContactSave(self):
        handle, attr = self.getUpdatedContactData()
        idx = self.handles.index(handle)
        self.rows[idx] = attr
        # Now get the sorted list from the server:
        srvidx = self.model.ListHandles(self.sortby).index(handle)
        if idx != srvidx:
            def move(list, x, y):
                temp = list[x]; del list[x]
                list.insert(y, temp)
            # and move our saved contact to it's sorted place:    
            move(self.handles, idx, srvidx)
            move(self.rows, idx, srvidx)
        self.textlist.remove(idx)
        self.textlist.insert(srvidx, attr)
        self.selectContact(handle)
          
    def __createWidgets(self):
        from MultiColumnTextList import MultiColumnTextList
        def dblclickcommand(self=self):
            idx = self.textlist.selected()
            self._dblclickcommand(self.handles[idx])
        def selectcommand(self=self):
            idx = self.textlist.selected()
            if idx is not None:
                self._selectcommand(self.handles[idx])
        self.rowconfigure(1, weight=1)
        self.columnconfigure(1, weight=1)
        self._btnSortby = Button(self, text="Sort by...",
            command=self.__Sortby)
        ToolTip.ToolTip(self._btnSortby, "select column to order by")    
        self._btnSortby.grid(sticky=NW)
        self._btnConfigure = Button(self, text="Configure Columns...",
            command=self.__ConfigureColumns)
        ToolTip.ToolTip(self._btnConfigure, "select columns to show")    
        self._btnConfigure.grid(row=0,column=1,sticky=NW)
        self.textlist = MultiColumnTextList(self,
            selectcommand=selectcommand,
            dblclickcommand=dblclickcommand,
            autocolresize=1,
            columnheader=1)
        self.textlist.setcolheader(self.fields_shown)
        self.textlist.setcolwidthsfromstr(self.fields_shown)
        self.textlist.grid(columnspan=2,sticky=W+S+E+N)
    def __tableKeyPress(self, event):
        key = event.keysym_num
        if (key > 65) and (key < 122):
            for fn in self.fns:
                if fn[0].upper() == chr(key).upper():
                    self.select_contact(fn)
    def __Sortby(self):
        import Pmw
        dialog = Pmw.SelectionDialog(self,
            title = 'Sort by',
            buttons = ('Ok', 'Cancel'),
            defaultbutton = 'Ok',
            scrolledlist_labelpos = 'n',
            label_text = 'Select Sort Column:',
            scrolledlist_items = vcard.FIELDNAMES)
        # We use str() here, because self.sortby could be unicode:    
        dialog.setvalue(str(self.sortby))
        dialog.see(vcard.FIELDNAMES.index(self.sortby))
        def applysortby(result, dlg=dialog, self=self):
            sels = dlg.getcurselection()
            if (result == "Ok") and (len(sels) > 0):
                debug.echo("Sortby %s" % sels[0])
                self.sortby = sels[0]
                Preferences.set("client.listview_sortby", self.sortby)
                self.updateList()
            dlg.deactivate(result)      
        dialog["command"] = applysortby
        dialog.activate()
    def __ConfigureColumns(self):
        from StringSetDialog import StringSetDialog
        dlg = StringSetDialog(self,
            title="Configure Columns",
            available_strings = vcard.FIELDNAMES,
            selected_strings = self.fields_shown,
            allowmultiselect=1)
        def cfgcolumns(btn, self=self, dlg=dlg):
            if btn == 'Ok':
                self.fields_shown = dlg.getvalue()
                Preferences.set('client.listview_columns', dlg.getvalue())
                self.textlist.setcolheader(dlg.getvalue())
                self.textlist.setcolwidths([])
                self.updateList()
            dlg.deactivate()    
        dlg['command'] = cfgcolumns
        dlg.activate()
    def selectContact(self, contact):
        try:
            handle = contact.handle()
        except:
            handle = contact
        try:
            idx = self.handles.index(handle)
            self.textlist.select(idx)
            self.textlist.see(idx)
        except ValueError:
            pass
    rows = []       
    def updateList(self):
        self.handles = self.model.ListHandles(sortby=self.sortby)
        self.rows = self.model.QueryAttributes(self.handles, self.fields_shown)
        self.textlist.clear()
        for row in self.rows:
            self.textlist.append(row)

