# Copyright (C) 2004 Henning Jacobs # # 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)