|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /usr/share/printconf/util/ |
Upload File : |
#!/usr/bin/python
## printconf_tui.py
program_name = "Red Hat Printer Config"
## Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
## Copyright (C) 2001 Crutcher Dunnavant <crutcher@redhat.com>,
## Copyright (C) 2002, 2003, 2004, 2005 Tim Waugh <twaugh@redhat.com>
## 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., 675 Mass Ave, Cambridge, MA 02139, USA.
# =====================================================================================================================
# Style
# -----
# This program was written in vim, using python highlighting, and 132 collumn display.
# If a 132 column display is unavailable, please return to the 1970s, with your hardware.
# =====================================================================================================================
# Purpose
# -------
# This program provides the text mode components to printconfs front-end.
# =====================================================================================================================
# Libs
# ----
# printconf
# ---------
# import the general parts of printconf
import locale
from rhpl.translate import _, N_, textdomain_codeset
locale.setlocale(locale.LC_ALL, "")
textdomain_codeset("printconf", locale.nl_langinfo(locale.CODESET))
from printconf_conf import *
import cups_import
if os.environ.has_key("PERLLIB"):
del os.environ["PERLLIB"]
if os.environ.has_key("PERL5LIB"):
del os.environ["PERL5LIB"]
# snack
# -----
# import snack, to provide our user interface
from snack import *
# =====================================================================================================================
# Generic Message Dialogs
tui = NameSpace()
tui.error = NameSpace()
tui.error.title = _("Error")
tui.error.buttons = [(_("Ok"), "ok")]
def tui_error(text):
ButtonChoiceWindow(main.screen, tui.error.title, text, tui.error.buttons)
tui.info = NameSpace()
tui.info.title = _("Info")
tui.info.buttons = [(_("Ok"), "ok")]
def tui_info(text):
ButtonChoiceWindow(main.screen, tui.info.title, text, tui.info.buttons)
tui.ask = NameSpace()
tui.ask.buttons = [(_("Yes"), "yes"), (_("No"), "no")]
def tui_ask(title, text):
if ButtonChoiceWindow(main.screen, title, text, tui.ask.buttons) == "yes":
return 1
return None
# =====================================================================================================================
# Save and Restart Status Dialog
# ------------------------------
srsd = NameSpace()
def srsd_run():
save_queues()
restart_lpd()
return 1
# =====================================================================================================================
# Exit Check Dialog
# -----------------
ecd = NameSpace()
ecd.title = _("Exit")
ecd.text = _("You have made changes, would you like to save them? If you say no, your changes will be lost.")
ecd.buttons = [(_("Yes"), "yes"), (_("No"), "no"), (_("Cancel"), "cancel")]
def ecd_run(screen):
called(ecd_run)
if conf.data_state == CURRENT:
main.run = 0
return 1
while 1:
choice = ButtonChoiceWindow(screen, ecd.title, ecd.text, ecd.buttons)
if choice == "yes":
if srsd_run():
main.run = 0
return 1
elif choice == "no":
main.run = 0
return 1
elif choice == "cancel":
return 0
# =====================================================================================================================
# New Queue Dialog
# ----------------
nqd = NameSpace()
nqd.title = _("Create a New Queue")
nqd.NAMETYPE = (21,0)
nqd.TYPEDATA = (10,3,4)
nqd.DRIVER= (3,4)
nqd.FINNISH= (0,0,4)
nqd.DONE= (0,-1,3)
nqd.CANCEL= (0,0,3)
nqd.state = None
nqd.data = {}
def nqd_run():
called(nqd_run)
nqd_init()
while nqd.state != nqd.DONE and nqd.state != nqd.CANCEL:
if nqd.state == nqd.NAMETYPE:
# name and type
nqd_nametype_run()
if nqd.state == nqd.TYPEDATA:
# type specific data
nqd_typedata_run()
if nqd.state == nqd.DRIVER:
# driver selection
nqd_driver_run()
if nqd.state == nqd.FINNISH:
nqd_finish()
if nqd.state == nqd.CANCEL:
return None
elif nqd.state == nqd.DONE:
return 1
else:
raise RuntimeError, "invalid nqd.state on termination"
def nqd_init():
called(nqd_init)
rerender = 0
locale = "C"
if os.environ.has_key("LANG"):
lang = os.environ["LANG"]
if (lang[0:2] == "zh" or lang[0:2] == "ko" or
lang[0:2] == "ja" or lang[0:2] == "ru"):
rerender = 1
if lang[0:2] == "ja":
locale = "ja_JP"
if lang[0:2] == "ko":
locale = "ko_KR"
if lang[0:5] == "zh_CN":
locale = "zh_CN"
if lang[0:5] == "zh_TW":
locale = "zh_TW"
nqd.state = nqd.NAMETYPE
nqd.data = {}
flags = {"convert_text_to_Postscript" : 1,
"assume_data_is_text" : rerender,
"rerender_Postscript" : rerender}
nqd.data["mf_flags"] = flags
if locale != "C":
nqd.data["filter_locale"] = locale
nqd.driver_tuple = None
nqd.queue_type_space = None
nqd.finish = NameSpace()
nqd.finish.title = _("Finish Making New Queue")
nqd.finish.instructions = _("About to create the following queue:")
nqd.finish.buttons = [(_("Finish"), "finish"), (_("Back"), "back"), (_("Cancel"), "cancel") ]
def nqd_finish():
called(nqd_finish)
# We do not validate type information here. It would be too complex.
# We instead trust that the stages which come before here have validated their info,
# if they have not, we fix them.
# init the form
local_form = GridForm(main.screen, nqd.nametype.title, 1, 3)
width = main.screen.width - 6 # 3 for each side
# Instructions
local_form.add(TextboxReflowed(width, nqd.finish.instructions), 0, 0)
# The summary
label_list = []
def addL(l_label, r_label, list=label_list):
list.append((l_label, r_label))
def addK(l_label, key, data = nqd.data, addL = addL):
addL(l_label, data[key])
addL(_("Type:"), nqd.queue_type_space.long_pretty_name)
if nqd.queue_type_space == queue_types.local:
addK(_("Device:"), "local_printer_device")
elif nqd.queue_type_space == queue_types.lpd:
addK(_("Server:"), "lpd_server")
addK(_("Lpd Queue:"), "lpd_queue")
elif nqd.queue_type_space == queue_types.smb:
addK(_("Share:"), "smb_share")
addK(_("IP:"), "smb_ip")
addK(_("Workgroup:"), "smb_workgroup")
addK(_("User:"), "smb_user")
elif nqd.queue_type_space == queue_types.ncp:
addK(_("Server:"), "ncp_server")
addK(_("Lpd Queue:"), "ncp_queue")
addK(_("User:"), "ncp_user")
elif nqd.queue_type_space == queue_types.jetdirect:
addK(_("IP:"), "jetdirect_ip")
addK(_("Port:"), "jetdirect_port")
if nqd.driver_tuple[0] == drivers.foomatic:
(printer, driver) = nqd.driver_tuple[1]
driver_desc = "%s %s %s" % (printer.make, printer.model, driver)
else:
driver_desc = nqd.driver_tuple[0].label
addL(_("Driver:"), driver_desc)
desc_grid = Grid(2, len(label_list))
local_form.add(desc_grid, 0, 1)
for i in range(len(label_list)):
(l_label, r_label) = label_list[i]
desc_grid.setField(Label(l_label), 0, i, padding = (0,0,1,0), anchorRight = 1)
desc_grid.setField(Label(r_label), 1, i, anchorLeft = 1)
# The buttons
button_bar = ButtonBar(main.screen, nqd.finish.buttons)
local_form.add(button_bar, 0, 2)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "finish":
if not nqd.queue_type_space.check() and \
not tui_ask(_("Warning"), nqd.queue_type_space.message):
continue
if nqd.driver_tuple[0] == drivers.foomatic:
black = driver_blacklist.dict.get(nqd.driver_tuple[1][1])
if black and not black.check() and \
not tui_ask(_("Warning"), black.message):
continue
construct_queue(nqd.queue_type_space, nqd.data, nqd.driver_tuple)
qld.selected_queue_name = nqd.data["queue_name"]
nqd.state = nqd.DONE
break
elif button == "back":
nqd.state = nqd.DRIVER
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
main.screen.popWindow()
nqd.nametype = NameSpace()
nqd.nametype.title = nqd.title + ": " + _("Name and Type")
nqd.nametype.buttons = [(_("Next"), "next"), (_("Cancel"), "cancel")]
nqd.nametype.name_label_prompt = _("Queue Name") + ":"
nqd.nametype.type_label_prompt = _("Queue Type")
nqd.nametype.bad_name = _("Invalid name")
nqd.nametype.taken_name = _("The name \"%s\" is already in use. Please choose a different name.")
def nqd_nametype_run():
called(nqd_nametype_run)
# init the form
nametype_form = GridForm(main.screen, nqd.nametype.title, 1, 3)
# the name prompt
name_grid = Grid(2,1)
nametype_form.add(name_grid, 0, 0)
name_grid.setField(Label(nqd.nametype.name_label_prompt), 0, 0, padding = (0, 0, 0, 1), anchorLeft = 1)
name_entry = Entry(20)
name_grid.setField(name_entry, 1, 0, anchorLeft = 1)
name_entry.set(nqd.data.get("queue_name", ""))
# the type listbox
type_grid = Grid(1,2)
nametype_form.add(type_grid, 0, 1)
type_grid.setField(Label(nqd.nametype.type_label_prompt), 0, 0, anchorLeft = 0)
type_box = CListbox(5, 2, [35, 9])
type_grid.setField(type_box, 0, 1, padding = (0,0,0,1))
type_box.append((queue_types.local.long_pretty_name, queue_types.local.type_name), queue_types.local)
type_box.append((queue_types.lpd.long_pretty_name, queue_types.lpd.type_name), queue_types.lpd)
type_box.append((queue_types.smb.long_pretty_name, queue_types.smb.type_name), queue_types.smb)
type_box.append((queue_types.ncp.long_pretty_name, queue_types.ncp.type_name), queue_types.ncp)
type_box.append((queue_types.jetdirect.long_pretty_name, queue_types.jetdirect.type_name), queue_types.jetdirect)
if nqd.queue_type_space:
type_box.setCurrent(nqd.queue_type_space)
# the button bar
button_bar = ButtonBar(main.screen, nqd.nametype.buttons)
nametype_form.add(button_bar, 0, 2)
while 1:
result = nametype_form.run()
# find the selected button
button = button_bar.buttonPressed(result)
# find the selected type
try:
queue_type_space = type_box.current()
except:
queue_type_space = None
if not queue_type_space:
continue
if button == "next":
queue_name = name_entry.value()
if not valid_queue_name(queue_name):
tui_error(nqd.nametype.bad_name)
continue
if not check_queue_name_uniqueness(queue_name, qld.queue_dict_dict, qld.alias_dict_dict):
tui_error(nqd.nametype.taken_name % queue_name)
continue
if not queue_type_space.check() and \
not tui_ask(_("Warning"), queue_type_space.message):
continue
nqd.data["queue_name"] = queue_name
nqd.queue_type_space = queue_type_space
nqd.state = nqd.TYPEDATA
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
main.screen.popWindow()
nqd.typedata = NameSpace()
nqd.typedata.handlers = {}
nqd.typedata.buttons = [(_("Next"), "next"), (_("Back"), "back"), (_("Cancel"), "cancel")]
def nqd_typedata_run():
called(nqd_typedata_run)
nqd.typedata.handlers[nqd.queue_type_space]()
nqd.typedata.local = NameSpace()
nqd.typedata.local.buttons = [(_("Next"), "next"), (_("Back"), "back"), (_("Custom"), "custom"), (_("Cancel"), "cancel")]
nqd.typedata.local.title = _("Setting Up") + " " + queue_types.local.long_pretty_name
nqd.typedata.local.device_label_prompt = _("Printer Device")
nqd.typedata.local.instructions = _("Pick the printer device from the list, or enter it using \"Custom\" below.")
nqd.typedata.local.explicit_device_prompt = _("Specify Device:")
nqd.typedata.local.col_labels = [_("Device"), _("Description")]
nqd.typedata.local.custom = NameSpace()
nqd.typedata.local.custom.title = _("Custom Device")
nqd.typedata.local.custom.text = _("Specify the device to use.")
nqd.typedata.local.custom.prompts = [_("Device File")]
def nqd_typedata_local_run():
called(nqd_typedata_local_run)
local_devices = scan_local_printer_devices(force = 1)
# init the form
local_form = GridForm(main.screen, nqd.typedata.local.title, 1, 3)
width = 60
height = main.screen.height
# the instructions
local_form.add(TextboxReflowed(width, nqd.typedata.local.instructions), 0, 0)
# the device clistbox
printer_width = 15
desc_width = width - printer_width
device_clistbox = CListbox(height - 16, 2, [printer_width, desc_width],
col_labels = nqd.typedata.local.col_labels, scroll = 1)
local_form.add(device_clistbox, 0, 1)
def populate_device_clist(local_devices = local_devices, clist = device_clistbox):
clist.clear()
keys = local_devices.keys()
keys.sort()
for key in keys:
device = local_devices[key]
if device.has_key("printer"):
desc = "%s %s" % (device["printer"].make, device["printer"].model)
elif device.has_key("auto"):
desc = device["auto"]["model"]
else:
desc = ""
clist.append([device["device"], desc], key)
local_printer_device = nqd.data.get("local_printer_device")
if local_printer_device:
if local_devices.has_key(local_printer_device):
clist.setCurrent(local_printer_device)
else:
clist.insert([local_printer_device, _("Custom")], local_printer_device, 0)
# the button bar
button_bar = ButtonBar(main.screen, nqd.typedata.local.buttons)
local_form.add(button_bar, 0, 2)
device_key = None
while 1:
populate_device_clist()
result = local_form.run()
# find the selected button
button = button_bar.buttonPressed(result)
# find the selected type
if button == "next":
try:
device_key = device_clistbox.current()
except:
tui_error(_("You must specify a device."))
continue
nqd.data["local_printer_device"] = device_key
nqd.state = nqd.DRIVER
break
elif button == "back":
nqd.state = nqd.NAMETYPE
break
elif button == "custom":
(res, vals) = EntryWindow(main.screen, nqd.typedata.local.custom.title,
nqd.typedata.local.custom.text, nqd.typedata.local.custom.prompts)
device_key = vals[0]
if res == "ok":
if not device_key:
tui_error(_("You must specify a device."))
else:
nqd.data["local_printer_device"] = device_key
nqd.state = nqd.DRIVER
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
dev = local_devices.get(device_key, None)
if dev and dev.has_key("printer"):
printer = dev["printer"]
printer_driver = printer.drivers[0]
if printer.driver:
# Use the recommended driver.
printer_driver = printer.driver
else:
for driver in printer.drivers:
black = driver_blacklist.dict.get(driver)
if not black or black.check():
printer_driver = driver
break
nqd.driver_tuple = (drivers.foomatic, (printer, printer_driver))
main.screen.popWindow()
nqd.typedata.lpd = NameSpace()
nqd.typedata.lpd.instructions = _("Enter the LPD server and queue to use.")
nqd.typedata.lpd.prompts = [_("Server"), _("Queue")]
nqd.typedata.lpd.title = _("LPD Data")
def nqd_typedata_lpd_run():
called(nqd_typedata_lpd_run)
while 1:
server_prompt = Entry(40)
server_prompt.set(nqd.data.get("lpd_server", ""))
queue_prompt = Entry(40)
queue_prompt.set(nqd.data.get("lpd_queue", ""))
prompts = ((nqd.typedata.lpd.prompts[0], server_prompt), (nqd.typedata.lpd.prompts[1], queue_prompt))
(button, (server, queue)) = EntryWindow(screen = main.screen,
title = nqd.typedata.lpd.title,
text = nqd.typedata.lpd.instructions,
prompts = prompts,
buttons = nqd.typedata.buttons)
# What do you expect to happen, after typing in a server, and then using Back->Next ?
nqd.data["lpd_server"] = server
nqd.data["lpd_queue"] = queue
if button == "next":
if server == "":
tui_error(_("You must specify a server."))
#elif queue == "": # This is legal, not overlooked
# tui_error(_("You must specify a queue."))
else:
nqd.state = nqd.DRIVER
break
elif button == "back":
nqd.state = nqd.NAMETYPE
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
nqd.typedata.smb = NameSpace()
nqd.typedata.smb.instructions = _("Enter the SMB share to use.")
nqd.typedata.smb.prompts = [_("Share"), _("Host IP"), _("Workgroup"), _("User"), _("Passwd")]
nqd.typedata.smb.title = _("Windows Printer (SMB) Data")
def nqd_typedata_smb_run():
called(nqd_typedata_smb_run)
while 1:
share_prompt = Entry(40)
share_prompt.set(nqd.data.get("smb_share", ""))
ip_prompt = Entry(40)
ip_prompt.set(nqd.data.get("smb_ip", ""))
workgroup_prompt = Entry(40)
workgroup_prompt.set(nqd.data.get("smb_workgroup", ""))
user_prompt = Entry(40)
user_prompt.set(nqd.data.get("smb_user", ""))
password_prompt = Entry(40, password = 1)
password_prompt.set(nqd.data.get("smb_password", ""))
prompts = ((nqd.typedata.smb.prompts[0], share_prompt),
(nqd.typedata.smb.prompts[1], ip_prompt),
(nqd.typedata.smb.prompts[2], workgroup_prompt),
(nqd.typedata.smb.prompts[3], user_prompt),
(nqd.typedata.smb.prompts[4], password_prompt))
(button, (share, ip, workgroup, user, passwd)) = EntryWindow(screen = main.screen,
title = nqd.typedata.smb.title,
text = nqd.typedata.smb.instructions,
prompts = prompts,
buttons = nqd.typedata.buttons)
# What do you expect to happen, after typing in a server, and then using Back->Next ?
nqd.data["smb_share"] = share
nqd.data["smb_ip"] = ip
nqd.data["smb_workgroup"] = workgroup
nqd.data["smb_user"] = user
nqd.data["smb_password"] = passwd
if button == "next":
if share == "":
tui_error(_("You must specify a SMB share to print to."))
else:
nqd.state = nqd.DRIVER
break
elif button == "back":
nqd.state = nqd.NAMETYPE
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
nqd.typedata.ncp = NameSpace()
nqd.typedata.ncp.instructions = _("Enter the NCP server and queue to use.")
nqd.typedata.ncp.prompts = [_("Share"), _("Queue"), _("User"), _("Passwd")]
nqd.typedata.ncp.title = _("Novell Netware Printer (NCP) Data")
def nqd_typedata_ncp_run():
called(nqd_typedata_ncp_run)
while 1:
server_prompt = Entry(40)
server_prompt.set(nqd.data.get("ncp_server", ""))
queue_prompt = Entry(40)
queue_prompt.set(nqd.data.get("ncp_queue", ""))
user_prompt = Entry(40)
user_prompt.set(nqd.data.get("ncp_user", ""))
password_prompt = Entry(40, password = 1)
password_prompt.set(nqd.data.get("ncp_password", ""))
prompts = ((nqd.typedata.ncp.prompts[0], server_prompt),
(nqd.typedata.ncp.prompts[1], queue_prompt),
(nqd.typedata.ncp.prompts[2], user_prompt),
(nqd.typedata.ncp.prompts[3], password_prompt))
(button, (server, queue, user, passwd)) = EntryWindow(screen = main.screen,
title = nqd.typedata.ncp.title,
text = nqd.typedata.ncp.instructions,
prompts = prompts,
buttons = nqd.typedata.buttons)
# What do you expect to happen, after typing in a server, and then using Back->Next ?
nqd.data["ncp_server"] = server
nqd.data["ncp_queue"] = queue
nqd.data["ncp_user"] = user
nqd.data["ncp_password"] = passwd
if button == "next":
if server == "":
tui_error(_("You must specify an NCP server to print to."))
elif queue == "":
tui_error(_("You must specify a queue on the NCP server to print to."))
else:
nqd.state = nqd.DRIVER
break
elif button == "back":
nqd.state = nqd.NAMETYPE
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
nqd.typedata.jetdirect = NameSpace()
nqd.typedata.jetdirect.instructions = _("Enter the Jetdirect ip and port to use.")
nqd.typedata.jetdirect.prompts = [_("Ip"), _("Port")]
nqd.typedata.jetdirect.title = _("Jetdirect (JETDIRECT) Data")
def nqd_typedata_jetdirect_run():
called(nqd_typedata_jetdirect_run)
while 1:
ip_prompt = Entry(40)
ip_prompt.set(nqd.data.get("jetdirect_ip", ""))
port_prompt = Entry(40)
port_prompt.set(nqd.data.get("jetdirect_port", "9100"))
prompts = ((nqd.typedata.jetdirect.prompts[0], ip_prompt),
(nqd.typedata.jetdirect.prompts[1], port_prompt))
(button, (ip, port)) = EntryWindow(screen = main.screen,
title = nqd.typedata.jetdirect.title,
text = nqd.typedata.jetdirect.instructions,
prompts = prompts,
buttons = nqd.typedata.buttons)
# What do you expect to happen, after typing in a server, and then using Back->Next ?
nqd.data["jetdirect_ip"] = ip
if not port:
port = "9100"
nqd.data["jetdirect_port"] = port
if button == "next":
if ip == "":
tui_error(_("You must specify the ip address of a JetDirect printer."))
else:
nqd.state = nqd.DRIVER
break
elif button == "back":
nqd.state = nqd.NAMETYPE
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
nqd.typedata.handlers[queue_types.local] = nqd_typedata_local_run
nqd.typedata.handlers[queue_types.lpd] = nqd_typedata_lpd_run
nqd.typedata.handlers[queue_types.smb] = nqd_typedata_smb_run
nqd.typedata.handlers[queue_types.ncp] = nqd_typedata_ncp_run
nqd.typedata.handlers[queue_types.jetdirect] = nqd_typedata_jetdirect_run
nqd.driverdata = NameSpace()
nqd.driverdata.title = _("Queue Driver")
nqd.driverdata.instructions = _("Select the Driver to use with this Queue.")
nqd.driverdata.buttons = [(_("Next"), "next"), (_("Back"), "back"), (_("Cancel"), "cancel")]
def nqd_driver_run():
called(nqd_driver_run)
# init the form
local_form = GridForm(main.screen, nqd.driverdata.title, 1, 3)
# Instructions
local_form.add(TextboxReflowed(main.width, nqd.driverdata.instructions), 0, 0)
# Driver Tree
tree_height = main.height - 4 # 1 Instructions, 3 buttons
tree_width = main.width #
driver_tree = driver_tree_checkboxtree(tree_height, tree_width)
local_form.add(driver_tree, 0, 1)
if nqd.driver_tuple:
driver_tree.setCurrent(nqd.driver_tuple)
# Buttons
button_bar = ButtonBar(main.screen, nqd.driverdata.buttons)
local_form.add(button_bar, 0, 2)
while 1:
# find the selected button
button = button_bar.buttonPressed(local_form.run())
# find the selected type
if button == "next":
driver_tuple = driver_tree.getCurrent()
if not driver_tuple or driver_tuple == NUL:
tui_error(_("You must specify a driver."))
else:
if driver_tuple[0] == drivers.foomatic:
black = driver_blacklist.dict.get(driver_tuple[1][1])
if black and not black.check():
if not tui_ask(_("Warning"), black.message):
continue
nqd.driver_tuple = driver_tuple
nqd.state = nqd.FINNISH
break
elif button == "back":
nqd.state = nqd.NAMETYPE
break
elif button == "cancel":
nqd.state = nqd.CANCEL
break
main.screen.popWindow()
# =====================================================================================================================
# driver_tree_checkboxtree
# ------------------------
#
# I need this exact widget in two places, better to hide its constructor, than have two slightly different versions.
# This tree is indexed by tuples of the form (foomatic_printer_overview, driver)
NUL = "IHATENEWTITSUCKORS"
def driver_tree_checkboxtree(height, width):
called(driver_tree_checkboxtree)
driver_tree = CheckboxTree(height = height, width = width, scroll = 1, hide_checkbox = 1, unselectable = 1)
# Special Cases
driver_tree.addItem(drivers.postscript.label, (snackArgs["append"], ), (drivers.postscript,))
driver_tree.addItem(drivers.text.label, (snackArgs["append"], ), (drivers.text,))
driver_tree.addItem(drivers.raw.label, (snackArgs["append"], ), (drivers.raw,))
make_offset = 3
makes = foomatic.make_model_dict_dict.keys()
makes.sort()
make_count = 0
for make in makes:
driver_tree.addItem(make, (snackArgs["append"], ), NUL)
model_dict = foomatic.make_model_dict_dict[make]
models = model_dict.keys()
models.sort()
model_count = 0
for model in models:
printer = model_dict[model]
path = (make_offset + make_count, snackArgs["append"], )
driver_tree.addItem(model, path, NUL)
for driver in printer.drivers:
d = driver
try:
if driver == printer.driver:
d = driver + " (*)"
except:
pass
path = (make_offset + make_count, model_count, snackArgs["append"], )
driver_tree.addItem(d, path, (drivers.foomatic, (printer, driver)))
model_count = model_count + 1
make_count = make_count + 1
return driver_tree
# =====================================================================================================================
# Queue Edit Dialog
# -----------------
qed = NameSpace()
qed.title = _("Edit Queue")
qed.buttons = [(_("Names"), "name"), (_("Type"), "type"), \
(_("Driver"), "driver"), (_("Done"), "done"), (_("Cancel"), "cancel")]
# Subdialogs:
# Name/Alias Edit
# Add/Edit Alias Edit
# Type/Type Data Edit
# Custom Device
# Change Type
# Driver Edit
# Driver Options Edit
def qed_run(queue_dict):
called(qed_run)
# This is cheap. We just save all of the old state, and restore it, if necessary.
backup_ctx = queue_edit.dynamic_queue_ctx.copy()
backup_state = conf.data_state
backup_name = queue_dict["queue"].name
conf.data_state = NOTSAVED
qed_init(queue_dict)
while 1:
# find the selected button
button = qed_display()
if button == "name":
qed_ned_run()
elif button == "type":
qed_ted_run()
elif button == "driver":
qed_ded_run()
elif button == "done":
type_space = queue_types.type_dict[queue_dict["queue"]["queue_type"].value]
if not type_space.check() and \
not tui_ask(_("Warning"), type_space.message):
continue
qld.selected_queue_name = demangle_queue_name(queue_dict["queue"].name)
return
elif button == "cancel":
queue_edit.dynamic_queue_ctx = backup_ctx
conf.data_state = backup_state
qld.selected_queue_name = demangle_queue_name(backup_name)
return
def qed_init(queue_dict):
called(qed_init)
qed.queue_dict = queue_dict
qed.queue = qed.queue_dict["queue"]
def qed_display():
called(qed_display)
local_form = GridForm(main.screen, qed.title, 1, 2)
# Type
q_type_space = queue_types.type_dict[qed.queue["queue_type"].value]
q_data = qed.queue["queue_data"]
label_list = []
def addL(l_label, r_label, list=label_list):
list.append((l_label, r_label))
def addK(l_label, key, q_data = q_data, addL = addL):
addL(l_label, q_data[key].value)
addL(_("Name:"), demangle_queue_name (qed.queue.name))
alias_width = main.screen.width - 6 - len(_("Aliases:"))
addL(_("Aliases:"), alias_list_string(qed.queue)[:alias_width])
addL(_("Type:"), q_type_space.long_pretty_name)
if q_type_space == queue_types.local:
addK(_("Printer Device:"), "local_printer_device")
elif q_type_space == queue_types.lpd:
addK(_("Server:"), "lpd_server")
addK(_("Lpd Queue:"), "lpd_queue")
elif q_type_space == queue_types.smb:
addK(_("Share:"), "smb_share")
addK(_("IP:"), "smb_ip")
addK(_("Workgroup:"), "smb_workgroup")
addK(_("User:"), "smb_user")
elif q_type_space == queue_types.ncp:
addK(_("Server:"), "ncp_server")
addK(_("Lpd Queue:"), "ncp_queue")
addK(_("User:"), "ncp_user")
elif q_type_space == queue_types.jetdirect:
addK(_("IP:"), "jetdirect_ip")
addK(_("Port:"), "jetdirect_port")
# Driver
addL(_("Driver:"), filter_description(qed.queue))
desc_grid = Grid(2, len(label_list))
local_form.add(desc_grid, 0, 0)
for i in range(len(label_list)):
(l_label, r_label) = label_list[i]
desc_grid.setField(Label(l_label), 0, i, padding = (0,0,1,0), anchorRight = 1)
desc_grid.setField(Label(r_label), 1, i, anchorLeft = 1)
# Button bar
button_bar = ButtonBar(main.screen, qed.buttons)
local_form.add(button_bar, 0, 1)
return button_bar.buttonPressed(local_form.runOnce())
qed.ned = NameSpace()
qed.ned.title = _("Edit Name and Aliases")
qed.ned.name_label = _("Name")
qed.ned.buttons = [(_("Add Alias"), "add"), (_("Edit Alias"), "edit"), \
(_("Delete Alias"), "delete"), (_("Done"), "done")]
qed.ned.alias_prompt = _("Alias:")
qed.ned.add_title = _("Add Alias")
qed.ned.add_text = _("Add an Alias")
qed.ned.edit_title = _("Edit Alias")
qed.ned.edit_text = _("Edit the alias")
qed.ned.bad_name = _("Invalid name")
qed.ned.taken_name = _("The name \"%s\" is already in use. Please choose a different name.")
def qed_ned_run():
called(qed_ned_run)
def populate_alias_listbox(alias_listbox):
alias_listbox.clear()
aliases = qed.queue["alias_list"][:]
aliases.sort(lambda a,b: cmp(a.value, b.value))
for alias in aliases:
alias_listbox.append(text = alias.value, item = alias)
local_form = GridForm(main.screen, qed.ned.title, 1, 3)
height = main.screen.height - 8 # 4 top, 4 bottom
width = main.screen.width - 6 # 6 sides
# Name Box
name_grid = Grid(2, 1)
local_form.add(name_grid, 0, 0)
name_grid.setField(Label(qed.ned.name_label), 0, 0)
name_entry = Entry(40)
name_grid.setField(name_entry, 1, 0)
name_entry.set(demangle_queue_name (qed.queue.name))
# Alias List
alias_listbox_height = height - 4 # 1 Name box, 3 buttons
alias_listbox = Listbox(height = alias_listbox_height, width = width, scroll = 1)
local_form.add(alias_listbox, 0, 1)
# Button Bar
button_bar = ButtonBar(main.screen, qed.ned.buttons)
local_form.add(button_bar, 0, 2)
while 1:
rectify_aliases(qed.queue)
populate_alias_listbox(alias_listbox)
# find the selected button
button = button_bar.buttonPressed(local_form.run())
name = name_entry.value()
if not valid_queue_name(name):
tui_error(qed.ned.bad_name)
continue
if not check_queue_name_uniqueness(name, qld.queue_dict_dict, qld.alias_dict_dict, qed.queue):
tui_error(qed.ned.taken_name % name)
continue
qed.queue.name = mangle_queue_name (name)
if button == "add":
entry = Entry(40)
(add_button, (a_name,)) = EntryWindow(main.screen, qed.ned.add_title, qed.ned.add_text, \
[(qed.ned.alias_prompt, entry)])
if add_button == "ok":
if not valid_queue_name(a_name):
tui_error(qed.ned.bad_name)
continue
if not check_queue_name_uniqueness(a_name, qld.queue_dict_dict,
qld.alias_dict_dict, qed.queue):
tui_error(qed.ned.taken_name % a_name)
continue
qed.queue["alias_list"].addData(AdmStringType, "alias").value = a_name
elif button == "edit":
try:
alias = alias_listbox.current()
except:
tui_error(_("You must select an alias to edit."))
continue
entry = Entry(40)
entry.set(alias.value)
(edit_button, (a_name,)) = EntryWindow(main.screen, qed.ned.edit_title, \
qed.ned.edit_text, [(qed.ned.alias_prompt, entry)])
if edit_button == "ok":
if not valid_queue_name(a_name):
tui_error(qed.ned.bad_name)
continue
if not check_queue_name_uniqueness(a_name, qld.queue_dict_dict,
qld.alias_dict_dict, qed.queue):
tui_error(qed.ned.taken_name % a_name)
continue
alias.value = a_name
elif button == "delete":
try:
alias = alias_listbox.current()
except:
tui_error(_("You must select an alias to delete."))
continue
alias.unlink()
elif button == "done":
break
rectify_aliases(qed.queue)
main.screen.popWindow()
qed.ted = NameSpace()
qed.ted.type_handlers = {}
qed.ted.buttons = [(_("Change Type"), "change"), (_("Done"), "done")]
def qed_ted_run():
called(qed_ted_run)
typespace_setup(qed.queue, qed.ted)
# These handles need to return false when they are done
qed.ted.run = 1
while qed.ted.run:
qed.ted.type_handlers[qed.ted.queue_type_space]()
typespace_apply(qed.queue, qed.ted)
qed.ted.local = NameSpace()
qed.ted.local.buttons = [(_("Custom"), "custom")]
qed.ted.local.buttons.extend(qed.ted.buttons)
qed.ted.local.title = _("Edit Local Printer")
qed.ted.local.custom = NameSpace()
qed.ted.local.custom.title = _("Custom Device")
qed.ted.local.custom.text = _("Specify the device to use.")
qed.ted.local.custom.prompts = [_("Device File")]
def qed_ted_local_handler():
called(qed_ted_local_handler)
qed.ted.local_devices = scan_local_printer_devices(force = 1)
height = main.screen.height - 8 # 4 top, 4 bottom
width = main.screen.width - 6 # 6 sides
local_form = GridForm(main.screen, qed.ted.local.title, 1, 2)
device_clistbox = CListbox(height = height - 3, col_widths = [20, width - 20 - 4], cols = 2, scroll = 1)
local_form.add(device_clistbox, 0, 0)
def populate_device_clist(devices = qed.ted.local_devices, clist = device_clistbox):
clist.clear()
keys = devices.keys()
keys.sort()
for key in keys:
device = devices[key]
if device.has_key("printer"):
desc = "%s %s" % (device["printer"].make, device["printer"].model)
elif device.has_key("auto"):
desc = device["auto"]["model"]
else:
desc = ""
clist.append([device["device"], desc], key)
if qed.ted.data.has_key("local_printer_device"):
local_printer_device = qed.ted.data["local_printer_device"]
if devices.has_key(local_printer_device):
clist.setCurrent(local_printer_device)
else:
clist.insert([local_printer_device, _("Custom")], local_printer_device, 0)
# Button bar
button_bar = ButtonBar(main.screen, qed.ted.local.buttons)
local_form.add(button_bar, 0, 1)
while 1:
populate_device_clist()
button = button_bar.buttonPressed(local_form.run())
# find the selected type
if button == "custom":
(res, vals) = EntryWindow(main.screen, qed.ted.local.custom.title,
qed.ted.local.custom.text, qed.ted.local.custom.prompts)
device_key = vals[0]
if res == "ok":
if not device_key:
tui_error(_("You must specify a device."))
else:
qed.ted.data["local_printer_device"] = device_key
break
elif button == "change":
qed_ted_change_type()
break
elif button == "done":
try:
device_key = device_clistbox.current()
except:
tui_error(_("You must specify a device."))
qed.ted.data["local_printer_device"] = device_key
qed.ted.run = None
break
main.screen.popWindow()
qed.ted.lpd = NameSpace()
qed.ted.lpd.instructions = _("Enter the LPD server and queue to use.")
qed.ted.lpd.prompts = [_("Server"), _("Queue"), _("Strict RFC1179")]
qed.ted.lpd.title = _("LPD Data")
def qed_ted_lpd_handler():
called(qed_ted_lpd_handler)
server_prompt = Entry(40)
server_prompt.set(qed.ted.data.get("lpd_server", ""))
queue_prompt = Entry(40)
queue_prompt.set(qed.ted.data.get("lpd_queue", ""))
strict_box = Checkbox(qed.ted.lpd.prompts[2])
if qed.ted.data.get("lpd_strict_rfc1179", None):
debug_print("strict == %s" % 1)
strict_box.setValue("*")
else:
debug_print("strict == %s" % 0)
strict_box.setValue(" ")
prompts = ((qed.ted.lpd.prompts[0], server_prompt), (qed.ted.lpd.prompts[1], queue_prompt),
("", strict_box))
(button, (server, queue, strict)) = EntryWindow(screen = main.screen,
title = qed.ted.lpd.title,
text = qed.ted.lpd.instructions,
prompts = prompts,
buttons = qed.ted.buttons)
qed.ted.data["lpd_server"] = server
qed.ted.data["lpd_queue"] = queue
qed.ted.data["lpd_strict_rfc1179"] = strict
if button == "change":
qed_ted_change_type()
elif button == "done":
if server == "":
tui_error(_("You must specify a server."))
#elif queue == "": # This is legal, not overlooked
# tui_error(_("You must specify a queue."))
else:
qed.ted.run = None
qed.ted.smb = NameSpace()
qed.ted.smb.instructions = _("Enter the SMB share to use.")
qed.ted.smb.prompts = [_("Share"), _("Host IP"), _("Workgroup"), _("User"), _("Passwd"), _("Translate \\n->\\r\\n")]
qed.ted.smb.title = _("Windows Printer (SMB) Data")
def qed_ted_smb_handler():
called(qed_ted_smb_handler)
share_prompt = Entry(40)
share_prompt.set(qed.ted.data.get("smb_share", ""))
ip_prompt = Entry(40)
ip_prompt.set(qed.ted.data.get("smb_ip", ""))
workgroup_prompt = Entry(40)
workgroup_prompt.set(qed.ted.data.get("smb_workgroup", ""))
user_prompt = Entry(40)
user_prompt.set(qed.ted.data.get("smb_user", ""))
password_prompt = Entry(40, password = 1)
password_prompt.set(qed.ted.data.get("smb_password", ""))
translate_box = Checkbox(qed.ted.smb.prompts[5])
if qed.ted.data.get("smb_translate", None):
translate_box.setValue("*")
else:
translate_box.setValue(" ")
prompts = ((qed.ted.smb.prompts[0], share_prompt),
(qed.ted.smb.prompts[1], ip_prompt),
(qed.ted.smb.prompts[2], workgroup_prompt),
(qed.ted.smb.prompts[3], user_prompt),
(qed.ted.smb.prompts[4], password_prompt),
("", translate_box))
(button, (share, ip, workgroup, user, passwd, translate)) = EntryWindow(screen = main.screen,
title = qed.ted.smb.title,
text = qed.ted.smb.instructions,
prompts = prompts,
buttons = qed.ted.buttons)
qed.ted.data["smb_share"] = share
qed.ted.data["smb_ip"] = ip
qed.ted.data["smb_workgroup"] = workgroup
qed.ted.data["smb_user"] = user
qed.ted.data["smb_password"] = passwd
qed.ted.data["smb_translate"] = translate
if button == "change":
qed_ted_change_type()
elif button == "done":
if share == "":
tui_error(_("You must specify a SMB share to print to."))
else:
qed.ted.run = None
qed.ted.ncp = NameSpace()
qed.ted.ncp.instructions = _("Enter the NCP server and queue to use.")
qed.ted.ncp.prompts = [_("Share"), _("Queue"), _("User"), _("Passwd")]
qed.ted.ncp.title = _("Novell Netware Printer (NCP) Data")
def qed_ted_ncp_handler():
called(qed_ted_ncp_handler)
server_prompt = Entry(40)
server_prompt.set(qed.ted.data.get("ncp_server", ""))
queue_prompt = Entry(40)
queue_prompt.set(qed.ted.data.get("ncp_queue", ""))
user_prompt = Entry(40)
user_prompt.set(qed.ted.data.get("ncp_user", ""))
password_prompt = Entry(40, password = 1)
password_prompt.set(qed.ted.data.get("ncp_password", ""))
prompts = ((qed.ted.ncp.prompts[0], server_prompt),
(qed.ted.ncp.prompts[1], queue_prompt),
(qed.ted.ncp.prompts[2], user_prompt),
(qed.ted.ncp.prompts[3], password_prompt))
(button, (server, queue, user, passwd)) = EntryWindow(screen = main.screen,
title = qed.ted.ncp.title,
text = qed.ted.ncp.instructions,
prompts = prompts,
buttons = qed.ted.buttons)
qed.ted.data["ncp_server"] = server
qed.ted.data["ncp_queue"] = queue
qed.ted.data["ncp_user"] = user
qed.ted.data["ncp_password"] = passwd
if button == "change":
qed_ted_change_type()
elif button == "done":
if server == "":
tui_error(_("You must specify an NCP server to print to."))
elif queue == "":
tui_error(_("You must specify a queue on the NCP server to print to."))
else:
qed.ted.run = None
qed.ted.jetdirect = NameSpace()
qed.ted.jetdirect.instructions = _("Enter the Jetdirect ip and port to use.")
qed.ted.jetdirect.prompts = [_("Ip"), _("Port")]
qed.ted.jetdirect.title = _("Jetdirect (JETDIRECT) Data")
def qed_ted_jetdirect_handler():
called(qed_ted_jetdirect_handler)
ip_prompt = Entry(40)
ip_prompt.set(qed.ted.data.get("jetdirect_ip", ""))
port_prompt = Entry(40)
port_prompt.set(qed.ted.data.get("jetdirect_port", "9100"))
prompts = ((qed.ted.jetdirect.prompts[0], ip_prompt),
(qed.ted.jetdirect.prompts[1], port_prompt))
(button, (ip, port)) = EntryWindow(screen = main.screen,
title = qed.ted.jetdirect.title,
text = qed.ted.jetdirect.instructions,
prompts = prompts,
buttons = qed.ted.buttons)
qed.ted.data["jetdirect_ip"] = ip
if not port:
port = "9100"
qed.ted.data["jetdirect_port"] = port
if button == "change":
qed_ted_change_type()
elif button == "done":
if ip == "":
tui_error(_("You must specify the ip address of a JetDirect printer."))
else:
qed.ted.run = None
qed.ted.type_handlers[queue_types.local] = qed_ted_local_handler
qed.ted.type_handlers[queue_types.lpd] = qed_ted_lpd_handler
qed.ted.type_handlers[queue_types.smb] = qed_ted_smb_handler
qed.ted.type_handlers[queue_types.ncp] = qed_ted_ncp_handler
qed.ted.type_handlers[queue_types.jetdirect] = qed_ted_jetdirect_handler
qed.ted.change_type = NameSpace()
qed.ted.change_type.title = "Change Type"
qed.ted.change_type.buttons = [(_("Ok"), "ok"), (_("Cancel"), "cancel")]
def qed_ted_change_type():
called(qed_ted_change_type)
height = main.screen.height - 8 # 4 top, 4 bottom
width = main.screen.width - 6 # 6 sides
local_form = GridForm(main.screen, qed.ted.change_type.title, 1, 2)
type_list = CListbox(height = height - 3, cols = 2, col_widths = [width - 10, 10], width = width)
local_form.add(type_list, 0, 0)
type_list.append([queue_types.local.long_pretty_name, queue_types.local.type_name], queue_types.local)
type_list.append([queue_types.lpd.long_pretty_name, queue_types.lpd.type_name], queue_types.lpd)
type_list.append([queue_types.smb.long_pretty_name, queue_types.smb.type_name], queue_types.smb)
type_list.append([queue_types.ncp.long_pretty_name, queue_types.ncp.type_name], queue_types.ncp)
type_list.append([queue_types.jetdirect.long_pretty_name, queue_types.jetdirect.type_name], queue_types.jetdirect)
type_list.setCurrent(qed.ted.queue_type_space)
button_bar = ButtonBar(main.screen, qed.ted.change_type.buttons)
local_form.add(button_bar, 0, 1)
while 1:
# find the selected button
button = button_bar.buttonPressed(local_form.run())
if button == "ok":
type_space = type_list.current()
if not type_space.check() and \
not tui_ask(_("Warning"), type_space.message):
continue
qed.ted.queue_type_space = type_space
break
elif button == "cancel":
break
main.screen.popWindow()
qed.driver = NameSpace()
qed.driver.title = _("Edit Driver")
qed.driver.buttons = [(_("Edit Driver Options"), "options"), (_("Done"), "done")]
def qed_ded_run():
called(qed_ded_run)
qed_ded_setup()
height = main.screen.height - 8 # 4 top, 4 bottom
width = main.screen.width - 6 # 6 sides
local_form = GridForm(main.screen, qed.driver.title, 1, 2)
driver_tree = driver_tree_checkboxtree(height = height - 3, width = width)
local_form.add(driver_tree, 0, 0)
if qed.driver.f_type == "NONE":
driver_tuple = (drivers.raw,)
elif qed.driver.f_type == "MAGICFILTER":
if qed.driver.foomatic.mf_type == "TEXT":
driver_tuple = (drivers.text,)
elif qed.driver.foomatic.mf_type == "POSTSCRIPT":
driver_tuple = (drivers.postscript,)
elif qed.driver.foomatic.mf_type == "MFOMATIC":
foo_printer = foomatic.id_dict.get(qed.driver.foomatic.printer_id)
if not foo_printer:
driver_tuple = (drivers.postscript,)
else:
if qed.driver.foomatic.gs_driver in foo_printer.drivers:
driver_tuple = \
(drivers.foomatic, (foo_printer, qed.driver.foomatic.gs_driver))
else:
# Well, they list a driver we dont have. Punt
driver_tuple = (drivers.foomatic, (foo_printer, foo_printer[0]))
else:
raise RuntimeError, "unknown type %s" % qed.driver.f_type
driver_tree.setCurrent(driver_tuple)
# Button bar
button_bar = ButtonBar(main.screen, qed.driver.buttons)
local_form.add(button_bar, 0, 1)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "options" or button == "done":
driver_tuple = driver_tree.getCurrent()
if driver_tuple[0] == drivers.foomatic:
black = driver_blacklist.dict.get(driver_tuple[1][1])
if black and not black.check():
if not tui_ask(_("Warning"), black.message):
continue
if not driver_tuple or driver_tuple == NUL:
tui_error(_("You must specify a driver."))
continue
else:
if driver_tuple[0] == drivers.raw:
qed.driver.f_type = "NONE"
elif driver_tuple[0] == drivers.text:
qed.driver.f_type = "MAGICFILTER"
qed.driver.foomatic.mf_type = "TEXT"
elif driver_tuple[0] == drivers.postscript:
qed.driver.f_type = "MAGICFILTER"
qed.driver.foomatic.mf_type = "POSTSCRIPT"
elif driver_tuple[0] == drivers.foomatic:
qed.driver.f_type = "MAGICFILTER"
qed.driver.foomatic.mf_type = "MFOMATIC"
qed.driver.foomatic.printer_id = driver_tuple[1][0].id
qed.driver.foomatic.gs_driver = driver_tuple[1][1]
if button == "options":
qed_ded_eod_run()
elif button == "done":
break
qed_ded_teardown()
main.screen.popWindow()
qed.driver.eod = NameSpace()
qed.driver.eod.title = _("Edit Driver Options")
qed.driver.eod.buttons = [(_("Edit"), "edit"), (_("Done"), "done")]
def qed_ded_eod_run():
called(qed_ded_eod_run)
local_form = GridForm(main.screen, qed.driver.eod.title, 1, 2)
option_listbox = Listbox(height = main.height - 3, width = main.width, scroll = 1)
local_form.add(option_listbox, 0, 0)
option_list = generate_option_list(qed.driver)
for i in range(len(option_list)):
option_listbox.append(option_list[i][2], i)
# Button bar
button_bar = ButtonBar(main.screen, qed.driver.eod.buttons)
local_form.add(button_bar, 0, 1)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "edit":
try:
index = option_listbox.current()
except:
continue
funcs = {
"bool":qed_ded_eod_bool_editor,
"int":qed_ded_eod_int_editor,
"float":qed_ded_eod_float_editor,
"enum":qed_ded_eod_enum_editor
}
apply(funcs[option_list[index][0]], option_list[index][1:])
elif button == "done":
break
main.screen.popWindow()
qed.driver.eod.opt = NameSpace()
qed.driver.eod.opt.buttons = [(_("Ok"), "ok")]
qed.driver.eod.opt.title = _("Edit %s")
def qed_ded_eod_bool_editor(key, label, dict, defval, ignored):
called(qed_ded_eod_bool_editor)
local_form = GridForm(main.screen, qed.driver.eod.opt.title % label, 1, 2)
checkbox = Checkbox(label, isOn = strtobool(dict.get((key, "bool"), defval)))
local_form.add(checkbox, 0, 0)
button_bar = ButtonBar(main.screen, qed.driver.eod.opt.buttons)
local_form.add(button_bar, 0, 1)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "ok":
dict[(key, "bool")] = strtobool(checkbox.value())
break
main.screen.popWindow()
def qed_ded_eod_int_editor(key, label, dict, defval, (max, min)):
called(qed_ded_eod_int_editor)
debug_print(type(defval))
i_defval = int(defval)
i_max = int(max)
i_min = int(min)
local_form = GridForm(main.screen, qed.driver.eod.opt.title % label, 1, 3)
local_form.add(Label(_("Integer: Min %s | Max %s") % (min, max)), 0, 0)
num_entry = Entry(10)
num_entry.set(str(dict.get((key, "int"), i_defval)))
local_form.add(num_entry, 0, 1)
button_bar = ButtonBar(main.screen, qed.driver.eod.opt.buttons)
local_form.add(button_bar, 0, 2)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "ok":
try:
val = int(num_entry.value())
except:
tui_error(_("Value must be a number"))
continue
if val > i_max:
val = i_max
if val < i_min:
val = i_min
dict[(key, "int")] = val
break
main.screen.popWindow()
def qed_ded_eod_float_editor(key, label, dict, defval, (max, min)):
called(qed_ded_eod_float_editor)
f_defval = float(defval)
f_max = float(max)
f_min = float(min)
local_form = GridForm(main.screen, qed.driver.eod.opt.title % label, 1, 3)
local_form.add(Label(_("Float: Min %s | Max %s") % (min, max)), 0, 0)
num_entry = Entry(10)
num_entry.set(str(dict.get((key, "float"), f_defval)))
local_form.add(num_entry, 0, 1)
button_bar = ButtonBar(main.screen, qed.driver.eod.opt.buttons)
local_form.add(button_bar, 0, 2)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "ok":
try:
val = float(num_entry.value())
except:
tui_error(_("Value must be a number"))
continue
if val > f_max:
val = f_max
if val < f_min:
val = f_min
dict[(key, "float")] = val
break
main.screen.popWindow()
def qed_ded_eod_enum_editor(key, label, dict, defval, enum_values):
called(qed_ded_eod_enum_editor)
local_form = GridForm(main.screen, qed.driver.eod.opt.title % label, 1, 2)
listbox = Listbox(height = main.height - 3, width = main.width)
local_form.add(listbox, 0, 0)
for (val, val_label) in enum_values:
listbox.append(text = val_label, item = val)
listbox.setCurrent(dict.get((key, "enum"), defval))
button_bar = ButtonBar(main.screen, qed.driver.eod.opt.buttons)
local_form.add(button_bar, 0, 1)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "ok":
dict[(key, "enum")] = listbox.current()
break
main.screen.popWindow()
qed.driver.ps_page_size_dict = {}
qed.driver.ps_page_size_dict["size_enums"] = [
("Letter", _("US Letter") ),
("Tabloid", _("Tabloid") ),
("Ledger", _("Ledger") ),
("Legal", _("Legal") ),
("Statement", _("Statement") ),
("Executive", _("Executive") ),
("A3", _("A3") ),
("A4" , _("A4") ),
("A5" , _("A5") ),
("B4" , _("B4") ),
("B5" , _("B5") ),
("Folio" , _("Folio") ),
("Quatro" , _("Quatro") ),
("10x14" , _("10x14") )
]
def qed_ded_setup():
called(qed_ded_setup)
driverspace_setup(qed.queue, qed.driver)
def qed_ded_teardown():
called(qed_ded_teardown)
driverspace_apply(qed.queue, qed.driver)
# =====================================================================================================================
# Test check dialog
# -----------------
tcd = NameSpace()
tcd.title = _("Test %s")
tcd.text = _("You have made changes, would you like to save them?\nIf you say no, you will not be able to print test pages.")
tcd.buttons = [(_("Yes"), "yes"), (_("No"), "no")]
def tcd_run(queue_name):
called(tcd_run)
if conf.data_state == CURRENT:
return 1
while 1:
choice = ButtonChoiceWindow(main.screen, tcd.title % queue_name, tcd.text, tcd.buttons)
if choice == "yes":
return srsd_run()
elif choice == "no":
return None
tcd.test_buttons = [(_("Test"), "test"), (_("Cancel"), "cancel")]
def test_queue_dialog(queue_dict):
called(test_queue_dialog)
queue_name = demangle_queue_name(queue_dict["queue"].name)
if not tcd_run(queue_name):
return
local_form = GridForm(main.screen, tcd.title % queue_name, 1, 2)
listbox = Listbox(height = main.height - 3, width = main.width)
local_form.add(listbox, 0, 0)
tests = collect_print_tests()
debug_print(tests)
for (test_file, test_desc_dict) in tests:
text = test_desc_dict["en"]
listbox.append(text = text, item = (test_file, text))
button_bar = ButtonBar(main.screen, tcd.test_buttons)
local_form.add(button_bar, 0, 1)
while 1:
button = button_bar.buttonPressed(local_form.run())
if button == "test":
(test_file, text) = listbox.current()
if not print_test_page(queue_name, conf.printconf_tests_dir + '/' + test_file):
tui_info(_("Sent %s to \"%s\".") % (text, queue_name))
else:
tui_error(_("There was an error trying to print the test page."))
break
elif button == "cancel":
break
main.screen.popWindow()
# =====================================================================================================================
# Delete Queue Dialog
# -------------------
def dqd_run(screen, queue_dict):
called(dqd_run)
if not queue_dict:
ButtonChoiceWindow(screen, _("Error"), _("You must select a printer queue to delete."), ["Ok"])
return 0
elif not queue_dict["editable"]:
ButtonChoiceWindow(screen, _("Error"), _("You cannot delete an imported printer."), ["Ok"])
return 0
delete = ButtonChoiceWindow(screen, _("Confirm Delete"),
_("Really delete \"%s\"?") % demangle_queue_name(queue_dict["queue"].name))
if delete == "ok":
if queue_dict["override"]:
qld.selected_queue_name = demangle_queue_name(queue_dict["queue"].name)
delete_queue_and_fix_default(queue_dict["queue"])
return 1
return 0
# =====================================================================================================================
# Queue List Dialog
# -----------------
# This section provides the queue list form interface, where users can pick a queue to edit, create a new one, test
# a queue, and delete a queue.
qld = NameSpace()
# No sense calling gettext every time, so we set the main form text up here
qld.qlist_labels = ["", _("Queue"), _("Aliases"), _("Type"), _("Details")]
qld.buttons = [(_("New"), "new"), (_("Edit"), "edit"), (_("Delete"), "delete"),
(_("Default"), "default"), (_("Test"), "test"), (_("Exit"), "exit")]
qld.selected_queue_name = None
def qld_selected_queue_dict():
called(qld_selected_queue_dict)
# find the selected queue
queue_dict = None
try:
queue_name = qld.queue_list_box.current()
if queue_name:
queue_dict = qld.queue_dict_dict[queue_name]
except:
pass
return queue_dict
def qld_run():
called(qld_run)
# build the main form. This will grab the existing printers
qld_build()
# reset the selected quene name, so we know it only gets used once
qld.selected_queue_name = None
while 1:
button = qld.button_bar.buttonPressed(qld.form.run())
queue_dict = qld_selected_queue_dict()
# all of the handlers return true IF they have done something that invalidates the qld
# current state, in which case we need to break.
if button == "new":
if nqd_run():
break
elif button == "edit":
if not queue_dict:
tui_error(_("You must select a printer queue to edit."))
continue
if not queue_dict["editable"]:
if queue_dict["queue"].protected:
tui_error(
_("This imported printer is protected from overrides. You can not edit it."))
continue
if tui_ask(_("Override?"),
_("This is an imported printer. Do you want to create a local override?")):
queue_name = demangle_queue_name(queue_dict["queue"].name)
override_queue(queue_name)
(qld.queue_dict_dict, qld.alias_dict_dict) = get_queues()
queue_dict = qld_selected_queue_dict()
else:
break
qed_run(queue_dict)
break
elif button == "delete":
if dqd_run(main.screen, queue_dict):
break
elif button == "default":
if queue_dict:
queue_name = demangle_queue_name(queue_dict["queue"].name)
set_default_queue_name(queue_name)
qld.selected_queue_name = queue_name
break
elif button == "test":
if not queue_dict:
tui_error(_("You must select a queue to print to."))
else:
test_queue_dialog(queue_dict)
elif button == "exit":
if ecd_run(main.screen):
break
else:
# Enable F12 functionality
if ecd_run(main.screen):
break
# clean off the main window
main.screen.popWindow()
def qld_build():
called(qld_build)
# create the form
qld.form = GridForm(main.screen, program_name, 1, 2)
# set up the queue list
# calc the column widths, yes, it is ugly
width = main.screen.width - 34 # 4 padding, 3 scrollbar, 6 screen edge, 2 state, 10 name, 9 type
rem = width - (int(width * 0.05) + int(width * 0.35) + int(width * 0.60))
col_widths = [2, 10 + int(width * 0.05), int(width * 0.35), 9, int(width * 0.60) + rem]
height = main.screen.height - 12 # 3 top, 9 bottom
# set up the widget
qld.queue_list_box = CListbox(height = height, cols = 5, col_widths = col_widths,
col_labels = qld.qlist_labels, scroll = 1)
qld.form.add(qld.queue_list_box, 0, 0)
# populate the queue list
default_queue_name = get_default_queue_name()
(qld.queue_dict_dict, qld.alias_dict_dict) = get_queues()
for queue_dict in sort_queues(qld.queue_dict_dict):
queue = queue_dict["queue"]
if demangle_queue_name (queue.name) == default_queue_name:
d = "+"
else:
d = " "
if not queue_dict["editable"]:
s = ">"
elif queue_dict["override"]:
s = "!"
else:
s = " "
if queue_dict["valid"]:
queue_type = queue["queue_type"].value
else:
queue_type = "INVALID" # This is programatic type info, and mustnt be translated.
qld.queue_list_box.append(
[d + s, demangle_queue_name (queue.name), alias_list_string(queue), queue_type, queue_details(queue)], demangle_queue_name (queue.name))
# set the selected queue, if necessary
if qld.selected_queue_name:
debug_print("setting current %s" % qld.selected_queue_name)
qld.queue_list_box.setCurrent(qld.selected_queue_name)
# Set up the button bar
qld.button_bar = ButtonBar(main.screen, qld.buttons)
qld.form.add(qld.button_bar, 0, 1)
# =====================================================================================================================
def tui_main_run():
called(tui_main_run)
# set up the edit environment
print _("Initializing alchemist edit environment ...")
init_queue_edit_or_die(main.dynamic_box_name)
# set up the foomatic environment
print _("Initializing linux printing database ...")
foomatic_init_overview()
if cups_import.import_needed ():
print _("Importing CUPS queues ...")
cups_import.import_cups_queues ()
conf.data_state = NOTSAVED
# set up snack
main.screen = SnackScreen()
main.height = main.screen.height - 8 # 4 top, 4 bottom
main.width = main.screen.width - 6 # 6 sides
# run the queue list form
main.run = 1
try:
while main.run:
qld_run()
except:
# tear down snack
main.screen.finish()
raise
# tear down snack
main.screen.finish()
updateconf = "/usr/share/printconf/util/updateconf.py"
os.spawnv (os.P_WAIT, updateconf, [ updateconf ])
sys.exit(0)
# =====================================================================================================================
# Import and Export
# -----------------
def export_cmd_run():
called(export_cmd_run)
init_queue_edit_or_die(main.dynamic_box_name)
print queue_edit.dynamic_queue_ctx
sys.exit(0)
def import_cmd_run():
called(import_cmd_run)
xmlstr = sys.stdin.read()
try:
ctx = AdmContext(xml = xmlstr)
except ValueError, e:
sys.stderr.write(_("Failed to parse alchemist context: \n%s") % e.args)
sys.exit(1)
if not valid_queue_ctx(ctx):
sys.stderr.write(_("Invalid printconf context"))
sys.exit(1)
init_queue_edit_or_die(main.dynamic_box_name)
force = 1
for arg in main.args:
if arg == "--force":
force = 1
elif arg == "--merge":
force = None
if force:
ctx.name = main.dynamic_box_name
queue_edit.dynamic_queue_ctx = ctx
else:
m_ctx = AdmContext(main.dynamic_box_name, 1, A = queue_edit.dynamic_queue_ctx, B = ctx)
queue_edit.dynamic_queue_ctx = m_ctx.strip()
save_queues()
updateconf = "/usr/share/printconf/util/updateconf.py"
os.spawnv (os.P_WAIT, updateconf, [ updateconf ])
sys.exit(0)
# =====================================================================================================================
def clear_cmd_run():
called(clear_cmd_run)
init_queue_edit_or_die(main.dynamic_box_name)
ctx = printconf_empty_ctx(main.dynamic_box_name)
queue_edit.dynamic_queue_ctx = ctx
save_queues()
sys.exit(0)
def default_cmd_run():
called(export_cmd_run)
init_queue_edit_or_die(main.dynamic_box_name)
queue_name = None
for arg in main.args:
if arg[:8] == "--queue=":
queue_name = arg[8:]
if not valid_queue_name(queue_name):
print _("\"%s\" is not a valid queue name.")
sys.exit(-1)
set_default_queue_name(queue_name)
save_queues()
sys.exit(0)
def add_local_cmd_run():
called(add_local_cmd_run)
# Examine the command line.
device = None
make = None
model = None
name = None
as_default = None
for arg in main.args:
if arg[:9] == "--device=":
device = arg[9:]
elif arg[:7] == "--make=":
make = arg[7:]
elif arg[:8] == "--model=":
model = arg[8:]
elif arg[:7] == "--name=":
name = arg[7:]
elif arg == "--as-default":
as_default = 1
if not (device and make and model):
sys.stderr.write (_("Need device, make and model.\n"))
sys.exit (1)
# Examine the current state of affairs.
foomatic_init_overview ()
init_queue_edit_or_die (main.dynamic_box_name)
(queue_dict_dict, alias_dict_dict) = get_queues ()
for queue_dict in sort_queues (queue_dict_dict):
if not queue_dict["valid"]:
# Not valid.
continue
queue = queue_dict["queue"]
if queue["queue_type"].value != queue_types.local.type_name:
# Not a local queue.
continue
queue_data = queue["queue_data"]
if queue_data["local_printer_device"].value != device:
# Not a queue for the specified device node.
continue
filter_data = queue["filter_data"]
if filter_data["mf_type"].value != "MFOMATIC":
# Not an mfomatic queue.
continue
p = foomatic.id_dict[filter_data["printer_id"].value]
if (p.auto_manufacturer != make or
p.auto_model != model) and \
(p.make != make or
p.model != model):
# Not a queue for this printer model.
continue
# Nothing to do.
debug_print("add-local: Nothing to do due to %s" % \
demangle_queue_name (queue.name))
sys.exit (0)
# Check that the provided name, if there is one, is unique.
if name and not check_queue_name_uniqueness (name, queue_dict_dict,
alias_dict_dict):
sys.stderr.write (_("add-local: queue name '%s' not unique\n"
% name))
sys.exit (1)
if not name:
# Generate a name.
name = string.replace (string.replace (device,
"/dev/usb/", "usb"),
"/dev/", "")
if not valid_queue_name (name):
name = string.replace (string.lower (make), " ", "")
if not valid_queue_name (name):
name = "printer"
# Is it unique?
if not check_queue_name_uniqueness (name, queue_dict_dict,
alias_dict_dict):
name = name + "-auto"
if not check_queue_name_uniqueness (name, queue_dict_dict,
alias_dict_dict):
sys.stderr.write (_("add-local: no suitable name available\n"))
sys.exit (1)
p = foomatic_match_printer (make, model)
if not p:
sys.stderr.write (_("add-local: No information available about %s %s\n" % (make, model)))
sys.exit (1)
# Build the queue information.
rerender = 0
locale = "C"
if os.environ.has_key("LANG"):
lang = os.environ["LANG"]
if lang[0:2] == "zh" or lang[0:2] == "ko" or lang[0:2] == "ja":
rerender = 1
if lang[0:2] == "ja":
locale = "ja_JP"
if lang[0:2] == "ko":
locale = "ko_KR"
if lang[0:5] == "zh_CN":
locale = "zh_CN"
if lang[0:5] == "zh_TW":
locale = "zh_TW"
data = {"local_printer_device" : device,
"queue_name" : name }
flags = {"convert_text_to_Postscript" : 1,
"assume_data_is_text" : rerender,
"rerender_Postscript" : rerender}
data["mf_flags"] = flags
if locale != "C":
data["filter_locale"] = locale
# If there is a recommended driver, try that first. Otherwise
# take the first one that's available.
printer_drivers = p.drivers
try:
printer_drivers.insert (0, p.driver)
except:
pass
printer_driver = printer_drivers[0]
for driver in printer_drivers:
black = driver_blacklist.dict.get (driver)
if not black or black.check():
printer_driver = driver
break
# Actually construct the queue.
construct_queue (queue_types.local, data, (drivers.foomatic,
(p, driver)))
if as_default:
set_default_queue_name (name)
save_queues ()
print _("Now run printconf-backend (or restart lpd service).")
sys.exit (0)
def remove_local_cmd_run():
called(remove_local_cmd_run)
# Examine the command line.
device = None
make = None
model = None
for arg in main.args:
if arg[:9] == "--device=":
device = arg[9:]
elif arg[:7] == "--make=":
make = arg[7:]
elif arg[:8] == "--model=":
model = arg[8:]
if not (device and make and model):
sys.stderr.write (_("Need device, make and model.\n"))
sys.exit (1)
init_queue_edit_or_die (main.dynamic_box_name)
(queue_dict_dict,alias_dict_dict) = get_queues ()
foomatic_init_overview ()
nearest_match_p = foomatic_match_printer (make, model)
if nearest_match_p:
nearest_make = nearest_match_p.make
nearest_model = nearest_match_p.model
else:
nearest_make = None
nearest_model = None
candidates = []
for queue_dict in sort_queues (queue_dict_dict):
if not queue_dict["valid"]:
# Not valid.
continue
queue = queue_dict["queue"]
if queue["queue_type"].value != queue_types.local.type_name:
# Not a local queue.
continue
queue_data = queue["queue_data"]
if queue_data["local_printer_device"].value != device:
# Not a queue for the specified device node.
continue
filter_data = queue["filter_data"]
if filter_data["mf_type"].value != "MFOMATIC":
# Not an mfomatic queue.
continue
try:
p = foomatic.id_dict[filter_data["printer_id"].value]
except:
foomatic_init_overview ()
p = foomatic.id_dict[filter_data["printer_id"].value]
if (p.auto_manufacturer != make or
p.auto_model != model) and \
(p.make != make or
p.model != model) and \
(p.make != nearest_make or
p.model != nearest_model):
# Not a queue for this printer model.
continue
# This queue is a candidate for removal.
candidates.append (queue)
if len (candidates) == 0:
# Nothing to do.
debug_print ("remove-local: No queue to remove")
sys.exit (0)
if len (candidates) > 1:
# Ambiguous.
debug_print ("remove-local: More than one candidate queue")
sys.exit (1)
delete_queue_and_fix_default (candidates[0])
save_queues ()
print _("Now run printconf-backend (or restart lpd service).")
sys.exit (0)
def match_driver_cmd_run():
called(match_driver_cmd_run)
# Examine the command line.
make = None
model = None
for arg in main.args:
if arg[:7] == "--make=":
make = arg[7:]
elif arg[:8] == "--model=":
model = arg[8:]
if not (make and model):
sys.stderr.write (_("Need make and model.\n"))
sys.exit (1)
# Try the quick way first: if the foomatic ID happens to be a
# new-style one then it is determined by the make/mfr strings.
id = make + "-" + model
id = id.replace (" ", "_")
os.environ["id"] = id
signal.signal (signal.SIGCHLD, signal.SIG_DFL)
cmdline = 'LC_ALL=C ' + foomatic.foomatic_configure_path + \
' -X -p "${id}" 2>/dev/null';
driver = None
for l in os.popen (cmdline, 'r').readlines ():
start = l.find ("<driver>")
if start == -1:
continue
end = l.find ("</driver>")
if end == -1:
continue
if end <= start:
continue
driver = l[start + 8:end]
if driver:
print driver
sys.exit (0)
foomatic_init_overview ()
p = foomatic_match_printer (make, model)
if not p:
# No match.
sys.exit (1)
try:
print p.driver
except:
print p.drivers[0]
sys.exit (0)
# =====================================================================================================================
def startup_and_find_cmd():
if os.geteuid() != 0:
print _("You must run printconf-tui as root.")
sys.exit(-1)
if "-h" in main.args or "--help" in main.args:
print main.usage
sys.exit(0)
main.dynamic_box_name = "local"
for arg in main.args:
if arg[:6] == "--box=":
main.dynamic_box_name = arg[6:]
# Look for commands
cmd = None
for arg in main.args:
if arg[0:3] == "--X":
if cmd:
sys.stderr.write(_("Conflicting commands: %s and %s") % (cmd, arg[3:]))
sys.exit(1)
else:
cmd = arg[3:]
if not cmd:
cmd = "tui"
if main.cmd_handlers.has_key(cmd):
main.cmd_handlers[cmd]()
else:
sys.stderr.write(_("No handler for command: ") + cmd)
sys.exit(1)
# =====================================================================================================================
# Main
# ----
main = NameSpace()
main.cmd_handlers = {
"tui" : tui_main_run,
"export" : export_cmd_run,
"import" : import_cmd_run,
"clear" : clear_cmd_run,
"default" : default_cmd_run,
"add-local" : add_local_cmd_run,
"remove-local" : remove_local_cmd_run,
"match-driver" : match_driver_cmd_run,
}
main.args = sys.argv[1:]
main.usage = """printconf-tui [--X<command>] [<options>]
options are:
-h, --help show usage
--box=box_name
set the edit box name. defaults to "local"
available commands:
tui run the normal tui mode. this is the default
export export the local printing settings
Ex: printconf-tui --Xexport > settings.xml
import import the local printing settings
Ex: printconf-tui --Ximport < settings.xml
options:
--force
overide the current settings with the imported settings,
this is the default.
--merge
merge the current settings with the imported settings.
default set the default name
Ex: printconf-tui --Xdefault --queue=foo
options:
--queue=queue_name
the name to set as the default. required.
clear clear all settings from the edit box
add-local add a new local printer queue
options:
--device=device
the device node to use (for example, /dev/lp0).
required.
--make=make
the IEEE 1284 MANUFACTURER string, or the printer
manufacturer's name as listed in the foomatic database.
required.
--model=model
the IEEE 1284 MODEL string, or the printer model as listed
in the foomatic database. required.
--name=name
name for the new queue. optional.
--as-default
set this as the default queue. optional.
remove-local remove a local printer queue
options:
--device=device
the device node used (for example, /dev/lp0). required.
--make=make
the IEEE 1284 MANUFACTURER string, or the printer
manufacturer's name as listed in the foomatic database.
required.
--model=model
the IEEE 1284 MODEL string, or the printer model as listed
in the foomatic database. required.
match-driver returns the best match driver for given make and model
an empty string is returned if no match can be made
options:
--make=make
the IEEE 1284 MANUFACTURER string, or the printer
manufacturer's name as listed in the foomatic database.
required.
--model=model
the IEEE 1284 MODEL string, or the printer model as listed
in the foomatic database. required.
"""