# Copyright (C) 2003 Konstantin Korikov
# 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
import sys
import gtk
import gtk.glade
import gobject
import os.path
import chestnut_dialer
import chestnut_dialer.importers
import chestnut_dialer.importers.importer
from chestnut_dialer import _
config_glade_file = os.path.dirname(__file__) + "/config.glade"
class FileNameArg:
box = None
entry = None
button = None
def __init__(self, arg_info):
self.box = gtk.HBox()
self.entry = gtk.Entry()
if arg_info.has_key("default"):
self.entry.set_text(arg_info["default"])
self.box.pack_start(self.entry, expand = 1, fill = 1)
self.button = gtk.Button(_("Select File"))
self.button.connect("clicked", self.select_file_action)
self.box.pack_start(self.button, expand = 0, fill = 1)
def destroy(self):
self.box = None
self.entry = None
self.button = None
def get_widget(self):
return self.box
def get_value(self):
return unicode(self.entry.get_text(), "UTF-8")
def select_file_action(self, *args):
wnd = gtk.FileSelection(_("Select File"))
wnd.set_filename(self.entry.get_text() or "~/")
wnd.ok_button.connect("clicked", self.file_selected_action, wnd)
wnd.cancel_button.connect("clicked", self.file_Select_cancel_action, wnd)
wnd.show_all()
wnd.set_modal(1)
def file_selected_action(self, btn, wnd):
self.entry.set_text(wnd.get_filename())
wnd.destroy()
def file_Select_cancel_action(self, btn, wnd):
wnd.destroy()
class StringArg:
entry = None
def __init__(self, arg_info):
self.entry = gtk.Entry()
if arg_info.has_key("default"):
self.entry.set_text(arg_info["default"])
def destroy(self):
self.entry = None
def get_widget(self):
return self.entry
def get_value(self):
return unicode(self.entry.get_text(), "UTF-8")
class OptionArg:
option = None
value = None
def __init__(self, arg_info):
self.option = gtk.OptionMenu()
values = []
menu = gtk.Menu()
for disp, value in arg_info["options"]:
menuitem = gtk.MenuItem(disp)
menu.append(menuitem)
menuitem.show()
menuitem.connect("activate",
self.option_activate, value)
values.append(value)
if self.value == None: self.value = value
self.option.set_menu(menu)
if arg_info.has_key("default"):
self.option.set_history(
values.index(arg_info["default"]))
self.value = arg_info["default"]
def destroy(self):
self.option = None
def get_widget(self):
return self.option
def get_value(self):
return self.value
def option_activate(self, mi, value):
self.value = value
class BooleanArg:
check = None
def __init__(self, arg_info):
self.check = gtk.CheckButton()
if arg_info.has_key("default"):
self.check.set_active(arg_info["default"])
def destroy(self):
self.check = None
def get_widget(self):
return self.check
def get_value(self):
return self.check.get_active()
class IntegerArg:
spin = None
def __init__(self, arg_info):
value = arg_info.has_key("default") and arg_info["default"] or 0
minumal = arg_info.has_key("min") and arg_info["min"] or -32000
maximal = arg_info.has_key("max") and arg_info["max"] or 32000
step = arg_info.has_key("step") and arg_info["step"] or 1
self.spin = gtk.SpinButton(
gtk.Adjustment(value, minumal, maximal, step), digits = 0)
def destroy(self):
self.spin = None
def get_widget(self):
return self.spin
def get_value(self):
return self.spin.get_value_as_int()
class ArgsBox:
widget = None
args = None
on_change_callback = None
tooltips = None
def __init__(self, args_info):
tbl = gtk.Table(len(args_info), 2)
tbl.set_border_width(5)
tbl.set_col_spacings(5)
tbl.set_row_spacings(5)
arg_types = {
"filename": FileNameArg,
"string": StringArg,
"option": OptionArg,
"boolean": BooleanArg,
"integer": IntegerArg}
self.args = []
row = 0
self.tooltips = gtk.Tooltips()
for arg_info in args_info:
l = (arg_info.has_key("display") and
arg_info["display"] or arg_info["name"])
label = gtk.Label(l)
arg = arg_types[arg_info["type"]](arg_info)
self.args.append(arg)
arg_widget = arg.get_widget()
c1, c2 = (label, arg_widget)
if arg_info.has_key("description"):
eb = gtk.EventBox()
eb.add(label)
self.tooltips.set_tip(eb, arg_info["description"])
c1 = eb
eb = gtk.EventBox()
eb.add(arg_widget)
self.tooltips.set_tip(eb, arg_info["description"])
c2 = eb
tbl.attach(c1, 0, 1, row, row + 1,
xoptions = 4, yoptions = 0)
tbl.attach(c2, 1, 2, row, row + 1,
xoptions = 5, yoptions = 0)
row += 1
self.tooltips.enable()
self.widget = tbl
def destroy(self):
for arg in self.args: arg.destroy()
self.args = None
self.widget.destroy()
self.widget = None
def get_values(self):
return map(lambda a: a.get_value(), self.args)
class ImportWindow:
window = None
accounts = None
acc_avaible_list = None
acc_import_list = None
cur_importer = None
cur_impid = None
reload_acount_list = None
args_cont = None
args_box = None
importer_desc_widget = None
importer_author_widget = None
statusbar = None
def __init__(self, accounts, reload_acount_list):
self.accounts = accounts
self.reload_acount_list = reload_acount_list
xml = gtk.glade.XML(config_glade_file, "ImportWindow",
chestnut_dialer.domain)
self.window = xml.get_widget("ImportWindow")
self.window.connect("destroy",
self.window_destroyed_event)
self.args_cont = xml.get_widget("ArgsBox")
self.acc_avaible_list = xml.get_widget("AvaibleList")
self.acc_import_list = xml.get_widget("ImportList")
self.importer_desc_widget = xml.get_widget("ImporterDescription")
self.importer_author_widget = xml.get_widget("ImporterAuthor")
self.statusbar = xml.get_widget("StatusBar")
def setup_list_widget(lst):
lst.set_model(gtk.ListStore(
gobject.TYPE_UINT, gobject.TYPE_STRING))
column = gtk.TreeViewColumn(_("Id"), gtk.CellRendererText(), text=0)
column.set_sort_column_id(0)
column.set_sort_indicator(True)
lst.append_column(column)
column = gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text=1)
column.set_sort_column_id(1)
column.set_sort_indicator(True)
lst.append_column(column)
lst.get_selection().set_mode(3)
lst.get_model().set_sort_column_id(1, gtk.SORT_ASCENDING)
setup_list_widget(self.acc_avaible_list)
setup_list_widget(self.acc_import_list)
importers = chestnut_dialer.importers.ls_importers()
if importers:
importers.sort(lambda a, b: cmp(a[1], b[1]))
menu = gtk.Menu()
for impid, prg in importers:
menuitem = gtk.MenuItem(prg)
menu.append(menuitem)
menuitem.show()
menuitem.connect("activate",
self.importer_activate, impid)
xml.get_widget("Importer").set_menu(menu)
self.importer_activate(None, importers[0][0])
xml.signal_connect("apply", self.apply_action)
xml.signal_connect("add", self.add_action)
xml.signal_connect("remove", self.remove_action)
xml.signal_connect("ok", self.ok_action)
xml.signal_connect("cancel", self.cancel_action)
def destroy(self):
if self.args_box:
self.args_cont.remove(self.args_box.widget)
self.args_box.destroy()
self.args_box = None
if self.window:
self.window.destroy()
self.window = None
self.accounts = None
def window_destroyed_event(self, *args):
self.destroy()
def show(self):
self.window.show_all()
def set_modal(self, modal):
self.window.set_modal(modal)
def apply_action(self, *args):
store = self.acc_avaible_list.get_model()
self.acc_import_list.get_model().clear()
try:
self.statusbar.push(1, _("Constructing importer..."))
###????
self.cur_importer = chestnut_dialer.importers.get_importer(
self.cur_impid, self.args_box.get_values())
for acc_name, acc_id in self.cur_importer.ls_accounts():
store.set(store.append(), 0, acc_id, 1, acc_name)
self.statusbar.push(1, _("Importer created"))
except chestnut_dialer.importers.importer.ConstructImporterException, e:
self.statusbar.push(1,
_("Failed to construct importer. Reason: %s") % e.msg)
def importer_activate(self, item, impid):
self.acc_import_list.get_model().clear()
self.acc_avaible_list.get_model().clear()
if self.args_box:
self.args_cont.remove(self.args_box.widget)
self.args_box.destroy()
self.cur_impid = impid
self.args_box = ArgsBox(
chestnut_dialer.importers.get_importer_args_info(self.cur_impid))
self.args_cont.pack_start(self.args_box.widget,
expand = 0, fill = 1)
self.args_cont.reorder_child(self.args_box.widget, 0)
self.args_cont.show_all()
imp_info = chestnut_dialer.importers.get_importer_info(
self.cur_impid)
if imp_info.has_key("description") and imp_info["description"]:
self.importer_desc_widget.set_text(imp_info["description"])
else: self.importer_desc_widget.set_text("")
if imp_info.has_key("author") and imp_info["author"]:
self.importer_author_widget.set_text(imp_info["author"])
else: self.importer_author_widget.set_text("")
self.cur_importer = None
self.statusbar.push(1,
_("Importer not created. Press Apply button for create it."))
def move_rows(self, source_list, dest_list):
src_ids = []
source_list.get_selection().selected_foreach(
lambda m, p, i, l: l.append(m.get_value(i, 0)), src_ids)
if len(src_ids) == 0: return
srcm = source_list.get_model()
destm = dest_list.get_model()
i = srcm.get_iter_first()
while i:
j = srcm.iter_next(i)
acc_id = srcm.get_value(i, 0)
acc_name = srcm.get_value(i, 1)
if acc_id in src_ids:
destm.set(destm.append(), 0, acc_id, 1, acc_name)
srcm.remove(i)
i = j
def add_action(self, *args):
self.move_rows(self.acc_avaible_list, self.acc_import_list)
def remove_action(self, *args):
self.move_rows(self.acc_import_list, self.acc_avaible_list)
def ok_action(self, *args):
if self.cur_importer:
m = self.acc_import_list.get_model()
i = m.get_iter_first()
while i:
acc_id = m.get_value(i, 0)
self.accounts.insert_account(
self.cur_importer.get_account(acc_id).copy())
i = m.iter_next(i)
self.destroy()
self.reload_acount_list()
def cancel_action(self, *args):
self.destroy()
|